解决php-fpm启动了端口监听但是不能连接的问题

CentOS7里面重启了一下php-fpm,然后发现服务不能用了,查看php-fpm是否正常监听:

netstat -lpn|grep php-fpm

显示端口监听正常,但是网站就是不能访问,telnet端口显示连接被拒绝,查看php-fpm的运行日志:

tail -100f /var/log/php-fpm/error.log

看不到任何异常,php-fpm默认是不打开子进程的日志输出的,手动打开:

vim /etc/php-fpm.d/xx.conf

修改内容: 

catch_workers_output = yes

重启服务: systemctl restart php-fpm

错误日志终于出来了:

WARNING: [pool www] child 24297 said into stderr: "ERROR: Connection disallowed: IP address '202.x.x.x' has been dropped."

原来是IP不在允许访问列表内的原因,再次修改配置文件:

vim /etc/php-fpm.d/xx.conf

listen.allowed_clients = 127.0.0.1,202.x.x.x

 
重启服务: systemctl restart php-fpm

一切正常了

 

 

解决OpenVPN “Waiting for TUN/TAP interface to come up”的问题

公司的VPN忽然连不上了,拨号成功后,OpenVPN 的日志中隔几秒就出现:

Route: Waiting for TUN/TAP interface to come up...

一段时间后直接出现失败的提示,虽然OpenVPN会变成绿色,并且鼠标移上去会显示出10开头的内网IP,但是其实是不能访问公司内网的,VPN并没有成功拨号。

在网上搜了一下,最终解决方案如下:

使用管理员权限打开cmd窗口,然后输入:

netsh winsock reset catalog
netsh int ipv4 reset reset.log

重启电脑即可解决。

 

解决 jps/jconsole NullPointerException 的问题

前阵子windows设置环境变量的时候卡死了,强制结束系统进程,结果导致用户环境变量全丢了,当时也没在意,后来使用jconsole的时候,问题来了,打开就报NPE空指针异常,无法调出选择连接的那个面板。网上搜了一下,发现有人使用JPS的时候,也报一样的错:

Exception in thread "main" java.lang.NullPointerException
at sun.jvmstat.perfdata.monitor.protocol.local.LocalVmManager.activeVms(LocalVmManager.java:148)
at sun.jvmstat.perfdata.monitor.protocol.local.MonitoredHostProvider.activeVms(MonitoredHostProvider.java:150)
at sun.tools.jps.Jps.main(Jps.java:62)

再搜了一下,有人给Java提交过一个bug,显示已经解决了

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
        at sun.jvmstat.perfdata.monitor.protocol.local.LocalVmManager.activeVms(LocalVmManager.java:127)
        at sun.jvmstat.perfdata.monitor.protocol.local.MonitoredHostProvider.activeVms(MonitoredHostProvider.java:133)
        at sun.tools.jconsole.ConnectDialog$ManagedVmTableModel.getManagedVirtualMachines(ConnectDialog.java:528)
        at sun.tools.jconsole.ConnectDialog$ManagedVmTableModel.refresh(ConnectDialog.java:511)
        at sun.tools.jconsole.ConnectDialog$ManagedVmTableModel.<init>(ConnectDialog.java:502)
        at sun.tools.jconsole.ConnectDialog.<init>(ConnectDialog.java:139)
        at sun.tools.jconsole.JConsole.showConnectDialog(JConsole.java:571)
        at sun.tools.jconsole.JConsole.access$100(JConsole.java:34)
        at sun.tools.jconsole.JConsole$4.run(JConsole.java:702)
        at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:461)
        at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:242)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:163)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)

这个bug详情很有用,看了这个大概知道是由于临时文件夹的问题引起的,echo %TMP%,发现是有路径的,start %TMP%,提示没权限。于是用管理员身份运行jconsole,一切正常了。然后修改用户环境变量,指向有权限的文件夹:C:\Users\xxx\AppData\Local\Temp,然后jconsole和jps终于可以正常使用了。

看来这个bug在后来的某个版本又被谁改回去了,应该再去Oracle把这个bug reopen一下。

Linux下获取网卡信息

#include <stdio.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define MAX_INTERFACE 64

int main(int argc, char const *argv[])
{
  printf("hello world!\n");
  showifs();
  return 0;
}

int showifs()
{
    int i;
    int rc;
    int sock;
    int ifnum;
    struct ifreq ifr[MAX_INTERFACE];
//    struct arpreq arp;
    struct ifconf ifc;

    sock = socket ( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
    if ( sock == -1 )
    {
        return -1;
    }

    ifc.ifc_len = sizeof( ifr );
    ifc.ifc_buf = ( caddr_t ) ifr;
    rc = ioctl ( sock, SIOCGIFCONF, &ifc );
    if ( rc == -1 )
    {
        close( sock );
        return -1;
    }

    ifnum = ifc.ifc_len / sizeof ( struct ifreq );
    fprintf( stdout, "ifnum=[%d]\n======================================\n", ifnum );
    for ( i = 0; i < ifnum; i ++ )
    {
        fprintf( stdout, "ifname%d [%s]\n", i, ifr[i].ifr_name );

        //ip
        rc = ioctl ( sock, SIOCGIFADDR, ifr + i );
        if ( rc != -1 )
        {
            fprintf( stdout, "IP=%s\n", inet_ntoa( ( ( struct sockaddr_in* )( &ifr[i].ifr_addr ) )->sin_addr ) );
        }

        //netmask
        rc = ioctl ( sock, SIOCGIFNETMASK, ifr + i );
        if ( rc != -1 )
        {
            fprintf( stdout, "NETMASK=%s\n", inet_ntoa( ( ( struct sockaddr_in* )( &ifr[i].ifr_netmask  ) )->sin_addr ) );
        }

        //broadcast
        rc = ioctl ( sock, SIOCGIFBRDADDR, ifr + i );
        if ( rc != -1 )
        {
            fprintf( stdout, "BROADCAST=%s\n", inet_ntoa( ( ( struct sockaddr_in* )( &ifr[i].ifr_broadaddr ) )->sin_addr ) );
        }

        //mac
        rc = ioctl ( sock, SIOCGIFHWADDR, ifr + i );
        if ( rc != -1 )
        {
            fprintf( stdout, "%02x:%02x:%02x:%02x:%02x:%02x\n",
                     ( unsigned char )ifr[i].ifr_hwaddr.sa_data[0],
                     ( unsigned char )ifr[i].ifr_hwaddr.sa_data[1],
                     ( unsigned char )ifr[i].ifr_hwaddr.sa_data[2],
                     ( unsigned char )ifr[i].ifr_hwaddr.sa_data[3],
                     ( unsigned char )ifr[i].ifr_hwaddr.sa_data[4],
                     ( unsigned char )ifr[i].ifr_hwaddr.sa_data[5] );
        }
    }

    close( sock );
    return 0;
}

 

让mysql支持emoji

emoji表情是通用的unicode字符串,不需要第三方工具支持,就可以显示丰富的表情图标,emoji表情由4个字节组成,mysql的utf8是3个字符,因此当emoji表情存入mysql数据库时会报错,通过一些设置可以让mysql支持emoji表情。

1.utf8mb4的最低mysql版本支持版本为5.5.3+,若不是,请升级到较新版本。
查看mysql版本的方法有:
在终端下:mysql -V
在mysql中:mysql> status;
使用mysql的函数:select version();
2.修改database、table和column字符集。参考以下语句:
ALTER DATABASE database_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE table_name CHANGE column_name VARCHAR(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
可以根据需要,在数据库层、表层或者字段层设置utf8mb4
3.修改mysql配置文件my.cnf(windows为my.ini)
my.cnf一般在etc/mysql/my.cnf位置。找到后请在以下三部分里添加如下内容:

[client]
default-character-set = utf8mb4

[mysql]
default-character-set = utf8mb4

[mysqld]
character-set-client-handshake = FALSE
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init_connect=’SET NAMES utf8mb4′

修改参数后需要重启mysql,重启后,在mysql命令行中输入:SHOW VARIABLES WHERE Variable_name LIKE ‘character_set_%’ OR Variable_name LIKE ‘collation%’;

检查是否如下:

+————————–+——————–+
| Variable_name            | Value              |
+————————–+——————–+
| character_set_client    | utf8mb4            |
| character_set_connection | utf8mb4            |
| character_set_database  | utf8mb4            |
| character_set_filesystem | binary            |
| character_set_results    | utf8mb4            |
| character_set_server    | utf8mb4            |
| character_set_system    | utf8              |
| collation_connection    | utf8mb4_unicode_ci |
| collation_database      | utf8mb4_unicode_ci |
| collation_server        | utf8mb4_unicode_ci |
+————————–+——————–+
rows in set (0.00 sec)

特别说明下:collation_connection/collation_database/collation_server如果是utf8mb4_general_ci,没有关系。但必须保证character_set_client/character_set_connection/character_set_database/character_set_results/character_set_server为utf8mb4。

5.如果你用的是java服务器,升级或确保你的mysql connector版本高于5.1.13,否则仍然无法使用utf8mb4
mysql连接字符串可参考:jdbc:mysql://localhost/dbname?useUnicode=true&characterEncoding=utf8&autoReconnect=true&failOverReadOnly=false
6.如果不打算重启mysql数据库,可以在数据库连接池中设置,建立连接后执行
SET NAMES utf8mb4,如DruidDataSource:

<property name="connectionInitSqls">
  <list>
    <value>set names utf8mb4</value>
  </list>
</property>

使用Navicat等客户端,如果查询出来的数据是乱码,也可先执行SET NAMES utf8mb4,然后再进行查询。

阿里云上面的mysql数据库,可以参考阿里云的官方文档:https://help.aliyun.com/knowledge_detail/5990076.html
emoji的表情列表,可参考:http://getemoji.com/