MySql 的 ONLY_FULL_GROUP_BY

最近把mysql 升级到了5.7.18 然后就发现了一个很明显的变化, ONLY_FULL_GROUP_BY 这个mysql mode 被加了进来, 按照sql 99 的标准这是好事.

但是实际上, mysql 的这个版本只能说almost identical or very close to, 不能说完全相等

简单的说,就是

That is, MySQL 5.7.5m15 will by default reject only those GROUP 
BY-queries that include non-aggregated expressions in the SELECT-list that 
are not functionally dependent upon the GROUP BY-list.

This not only means that you cannot mess up your GROUP BY-queries anymore 
(as MySQL will now reject an improper GROUP BY query), 
it will also not require you to write non-sensical "dummy" aggregates
 over expressions that can only have one value per aggregated 
result row. Hurrah!

详细的解释请看这篇文章:

http://rpbouman.blogspot.nl/2014/09/mysql-575-group-by-respects-functional.html

php-fpm 内存过高,CPU占有率过高带来的优化和调整

如果不是昨天我的论坛遭受到了NTP DDos攻击,我也不会遇到这个问题.

首先,这些问题都是和php-fpm 的配置有关,如果你使用的是军哥的LNMP,那么这个配置文件位于

/usr/local/php/etc/php-fpm.conf

首先先解决内存过高的问题,这个是由于php-fpm占用了内存以后并没有及时释放造成的,但是我们可以通过配置文件强制他释放内存,可以在配置文件里面加上

pm.max_requests = 500

500这个值适用于大部分的服务器配置,但是如果你的内存过大或者过小,可以适当增大或者减小这个值,取决于你的内存的实际使用率. 

既然说到了php-fpm 的配置,那么就得好好的说下php-fpm 的 process management

php-fpm 的process management 有两种工作方式,一种是static, 一种是dynamic, 对于小的cloud 或者vps 一般用static,但是其实大部分时间我们都在使用dynamic

pm = dynamic
pm.max_children = 160
pm.start_servers = 20
pm.min_spare_servers = 20
pm.max_spare_servers = 40

和process management 有直接关系的是这四个参数, pm.max_children 在pm=static 的时候有用,在pm = dynamic 的时候, 剩下三个参数才开始起作用

这里问题的关键在于,如何设置pm.max_children 的值

对于不同的php application,每个php-fpm instance 占用的内存也不一样,需要具体application 具体分析,但是这里我们可以去个average , 30M

假设你的服务器有8G的内存,其中的6GB 可以划给php-fpm, 那么

pm.max_children = 6000MB / 30MB =200

也就是说在这种情况下,200这个值是比较合适的. 这里需要注意的是,赋予max_children 一个很高的值,并不代表会带来高性能,也许会拖垮整个服务器

剩下的三个参数,按照实际情况,设置的差不多就行了

你可以用如下的命令来实际查看一下single php-fpm usage:

ps --no-headers -o "rss,cmd" -C php-fpm | awk '{ sum+=$1 } END { printf ("%d%s\n", sum/NR/1024,"M") }'

另外别忘了开启php-fpm 的 slowlog,这样方便你以后查看日志来进行debug

slowlog = /usr/local/php/var/log/slow.log

对于CPU 占有率过高的问题,这个其实并不是php-fpm 的问题,而是你写的php 代码的问题,这个时候可以通过设置pm.status_path 开查看到底是哪个php application 占用的cpu 资源

详细可以参见这篇文章:

https://brandonwamboldt.ca/understanding-the-php-fpm-status-page-1603/

 

对于iptables 的一点理解

这是无意中在stackoverflow上看到的,以前还真没有注意到.

Question:

I was trying to block an ip of ( network stresser tool – a ddos websites selling ddos bots by seconds online ) the first one i was trying to block with iptables :

iptables -A INPUT -d 173.193.26.73 -j DROP
iptables -A INPUT -s 173.193.26.73 -j DROP
however i still see the ip and bandwidth still up on iftop. also still see the ip going on tcpdump.

is that normal? what’s the problem in here?

 

Answer: 

Yes, it’s normal. iptables doesn’t stop inbound traffic turning up on your physical interface, thus notching up your iftop counts, and it doesn’t stop the kernel seeing that it’s there, hence the tcpdump output. It does, however, stop the kernel passing the traffic on to anything that might be listening for it.

If you see any output traffic in response to those input packets, something’s wrong. But otherwise, no, that’s normal.

iptables 工作在5个链上, prerouting, input, forward, output, postrouting

prerouting 和 postrouting 一般是在NAT上使用,所以traffic 会流经CPU,也即是说iptables 无法阻止真实网卡的流入流量, 因此itfop 和 tcpdump 都能看到流入的流量,但是在用iptables block了这个IP的情况下,是不会有流出的流量的.

 

简单的防DDos和CC attack 的一点补救措施

其实这些措施也基本没有什么大用,在代理IP 足够多的情况下只能依靠硬件去防守,但是聊胜于无

首先可以看下hivelocity 的一篇文章

https://www.hivelocity.net/kb/how-to-check-if-your-linux-server-is-under-ddos-attack/

1 安装CSF, 这个应该在我的所有服务器上都有安装

2 check the number of active connections sorted by asc

netstat -n | grep ':80' | awk -F' ' '{print $5}' | awk -F':' '{print$1}' | sort | uniq -c | sort -n

By Desc:

netstat -n | grep ':80' | awk -F' ' '{print $5}' | awk -F':' '{print$1}' | sort | uniq -c | sort -n -r

3 install iftop

yum install epel-release -y

yum install iftop -y

iftop -n

 

4 fail2ban 在一定情况下还是有作用的

5 Check average single php-fpm instance memory usage:

ps --no-headers -o "rss,cmd" -C php-fpm | awk '{ sum+=$1 } END { printf ("%d%s\n", sum/NR/1024,"M") }'

Online.net Xenserver 使用RPN-SAN的诸多问题

Online.net 的系统本身就有很多问题,加上XenServer 以后问题就更多了,再加上RPN – SAN 以后,那问题就更更更多了。。。

为什么要是用RPN-SAN? 

因为online.net 的服务器很多都是纯SSD 服务器,如果我们需要放置大量的图片的话,显然是不够的,这个时候RPN-SAN 就派上用场了, 在纯dedicated server上使用SAN,那是很容易的事情,直接挂载就可以了,在XenServer上挂载iSCSI 的 SAN,则稍微麻烦点, 有几点注意事项:

  1. XenServer 7 是建立在CentOS 7 上面的, iSCSI用的port 是3260, 所以需要在防火墙上打开3260
  2. Online.net 的RPN-SAN 用的是内网,位于 10.88.0.0/14. 如果你的online.net 的服务器是用的IPMI 安装的系统,那么你需要把这台服务器自带的Private IP 配置上. 关于private ip 的 netmask,和gateway 可以先用DHCP 激活,然后自己记录下来,稍后你可以一直使用DHCP,或者按照自己的意愿使用static
  3. 在购买完了Online.net 的 RPN-SAN以后,你需要在此RPN-SAN的管理页面,给使用此RPN-SAN 的dedicated server授权,这是从security 的角度考虑
  4. 于此同时,你还需要在RPN Group里面,把RPN-SAN 和使用此SAN 的服务器放置于同一个Group里面
  5. 一般来说,RPN-SAN 和 服务器的Private IP 需要在一个网段,我们这里可以使用10.88.0.0/14 或者10.90.0.0/15
  6. XenServer 需要手动添加一条面向private network 10.88.0.0/14 或者10.90.0.0/15的 route,这样是他们互相通信,为了方便,此文下面假设我们使用的是10.90.0.0/15这个网段
  7. XenServer 通过xapi 添加static route 的办法:
xe network-list
xe network-param-set uuid=<UUID> other-config:static-routes=10.90.0.0/15/10.90.23.1

在这命令里面,我们的网卡为xenbr2,IP 为10.90.23.44, Gateway 为10.90.23.1

运行完这条命令, 如果我们使用route -n 来查看route, 会发现没有任何变化, 这是因为我们需要重启系统或者运行xe-toolstack-restart 来使新的配置生效

添加static route 很简单,但是删除就比较麻烦了. 删除的话,需要一次性删除所有的static route,然后再添加我们认为必须的route.

删除所有static route:

xe network-param-remove uuid={network UUID} param-name=other-config param-key=static-routes

If there were some needed static route, add them back, for example:

xe network-param-set uuid={network UUID} other-config:static-routes=192.168.98.0/24/192.168.1.1,192.168.99.0/24/192.168.1.1

 

After that, reboot to make them take effect.

对于storage来说,我们经常会把NIC 的MTU 改为9000, steps to modify MTU in Senserver:

  1. shutdown guests
  2. reconfigure network

xe network-param-set uuid=<network-uuid> MTU=9000

      3. reboot hosts

       4. verify proper MTU sizing

俩教训。。。

最近一周有点郁闷,浪费了太多的时间

  1. 手上有两台朋友公司退下来的低配置的笔记本,跑windows有点问题,但是跑ubuntu来写代码没有任何问题. 于是按一贯的套路去安装virtualbox,vagrant, laravel。。。结果发现vagrant up 就是无法启动虚拟机,总是卡在ssh auth 这一步、、、结果debug了一个星期,才发现原来是CPU 不支持VT-X。。虽然主板支持,但是没有任何用。。nnd。。还是正常使用吧,别用什么虚拟机了
  2. 自己的几个websites 用的是piwik 来做visitor analyse, 但是其中一个站点我今天enable了 cloudflare SSL 就发现无法追踪visitor了。。。突然想起来莫非是没有装ssl 的piwik 无法记录有SSL 的website? 后来一看。。果然还真是这个问题。。。

 

哎,最近诸事不顺啊。。

详细版的nginx和php-fpm 优化教程

这篇文章承接上文,是相对来说比较详细的教程:

Nginx Tip 1. – Organize Nginx Configuration Files

Normally Nginx configuration files are located under /etc/nginx path.
One good way to organize configuration files is use Debian/Ubuntu Apache style setup:

## Main configuration file ##
/etc/nginx/nginx.conf

## Virtualhost configuration files on ##
/etc/nginx/sites-available/
/etc/nginx/sites-enabled/

## Other config files on (if needed) ##
/etc/nginx/conf.d/

更多

优化nginx和 php-fpm 的十个技巧

这是在highscability.com上看到的,仔细一看的话,其实也没有什么东西:

  1. Switch from TCP to UNIX domain sockets. When communicating to processes on the same machine UNIX sockets have better performance the TCP because there’s less copying and fewer context switches.
  2. Adjust Worker Processes. Set the worker_processes in your nginx.conf file to the number of cores your machine has and increase the number of worker_connections.
  3. Setup upstream load balancing. Multiple upstream backends on the same machine produce higher throughout than a single one.
  4. Disable access log files. Log files on high traffic sites involve a lot of I/O that has to be synchronized across all threads. Can have a big impact.4
  5. Enable GZip.
  6. Cache information about frequently accessed files.
  7. Adjust client timeouts.
  8. Adjust output buffers.
  9. /etc/sysctl.conf tuning.
  10. Monitor. Continually monitor the number of open connections, free memory and number of waiting threads and set alerts if thresholds are breached. Install the NGINX stub_status module.

使用自签发的SSL证书来加密nginx与后端服务器的通讯

这个问题很有意思,说起来还是由于可恶的GFW. 我目前使用一台阿里云华南的服务器来服务国内客户,然后用一台阿里云HKB 的服务器 + CDN 来服务国外客户. 但是郁闷的是,HKB 的服务器,nginx运行一会就回出现502 bad gateway,但是把HKB 的业务放在其他的服务商那里,就不会出现这个问题, 而且如果你不是用80端口,也不会出现这个问题

这个debug了将近一个星期才猛然间意识到,这也许是因为GFW 和阿里云盾的敏感词过滤系统,强制TCP 触发RST标志,造成502 connection reset

目前看来唯一的办法就是上https, 也就是说要secure data transfer between nginx and its upstream。。。我发现对我来说,还是英语描述比较完整

在这种情况下,nginx 的 upstream 要是用https, 但是因为只是作为内部数据传输,因此可以不用去买SSL证书,直接用self signed 的证书就可以了.

nginx 的官方,有一篇比较权威的教程:

https://www.nginx.com/resources/admin-guide/nginx-https-upstreams/

但是说实话,这个比较复杂,用的是SSL 的双面认证,类似于国内的网上银行的验证方式,而对于我们这种情况,只需要单向认证就可以了. 也就是说只需要在 后端的nginx 的服务器上安装自签发的SSL证书即可,前端nginx 配置调整为proxy_pass https.

关于如何给nginx安装自签发的ssl 证书,国内的教程也比较多,但是大部分都是先自建CA key crt,再签发,比较麻烦, 类似于这样:

http://blog.creke.net/762.html

这样做比较适合双向SSL认证

一个简单的方式可以借助下面的blog提到的方式:

http://blog.topspeedsnail.com/archives/3768

下面简单说下:

现在很多网站都使用https进行加密通讯及对网络服务器身份的鉴定。这遍文章介绍怎么在Nginx web服务上设置自签名SSL证书。由于不是由权威机构发布的证书,它(自签名证书)不能确认网络服务器身份,但是它可以对通信进行加密。

自签名证书适合个人或公司内部使用,如果要对外提供web服务,最好购买权威机构发布的证书。在github上有一个项目叫Let’s Encrypt,可以使用它签发免费的证书,并且大多数web浏览器都信任它。

创建SSL证书

我们可以创建一个目录用来存放所有SSL相关文件,在/etc/nginx下创建:

创建 SSL密钥和证书文件:

$ sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crt

我们来看一看上面命令各个选项的意思:

openssl:这是创建和管理OpenSSL密钥、证书和其它文件的命令行工具
req:指定使用X.509证书签名要求(CSR)
-x509:创建自签名证书,而不生成签名请求
-nodes:证书不使用密码,我们需要Nginx能直接读取文件,在重启Nginx时,不用输入密码
-days 365::证书的有效时间,这里是一年
-newkey rsa:2048:同时生成一个新证书和新密钥,RSA密钥长度:2048位
-keyout:密钥生成的路径
-out:证书生成的路径
执行上面命令,需要回答一系列问题。其中,最重要的一个问题是Common Name (e.g. server FQDN or YOUR name),输入你的域名。这里可以使用泛解析. 如果没有域名的话,使用ip地址。

这样就会生产key 和 crt

一个简单的nginx配置例子:

server {
 listen 80 default_server;
 listen [::]:80 default_server ipv6only=on;
 
 listen 443 ssl;
 
 root /usr/share/nginx/html;
 index index.html index.htm;
 
 server_name your_domain.com;
 ssl_certificate /etc/nginx/ssl/nginx.crt;
 ssl_certificate_key /etc/nginx/ssl/nginx.key;
 
 location / {
 try_files $uri $uri/ =404;
 }
}