升级http 2.0

近两年tengine和nginx的在新特性的支持上差距越来越大。处于尝试新事物的好奇,动手升级到nginx-1.9.9。整个过程非常曲折,不再细说。。 主要的配置差异实际很小 listen 443 ssl so_keepalive=on spdy; 改为 listen 443 ssl so_keepalive=on http2; 但是因为之前开启了ssl_prefer_server_ciphers,升级前没仔细看过nginx官方的wiki,所以吃了不少苦头。升级之后页面直接就打不了, chrome 报错ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY。 Note that accepting HTTP/2 connections over TLS requires the “Application-Layer Protocol Negotiation” (ALPN) TLS extension support, which is available only since OpenSSL version 1.0.2. Using the “Next Protocol Negotiation” (NPN) TLS extension for this purpose (available since OpenSSL version 1.0.1) is not guaranteed. 搞定了http2后,另外奇葩的事情是blog打开就是空白的。php-fpm等运行正常,最终发现是nginx官方deb包里的fastcgi_params是错的,该用之前tengine使用的配置搞定。参考:1.http://nginx.org/en/docs/http/ngx_http_v2_module.html

December 12, 2015 · 1 min · pm

屏蔽迅雷盗链下载文件

不经意间发现绝大部分流量都是来自于迅雷,一看日志里都是在下载各种硕大的ISO文件,而且每个请求下周的size也不大。为了保证正常请求能有充足的资源处理,就得把这部分请求屏蔽掉。统计了一下迅雷现在使用的UA多得不得了,很难简单的跟进UA来处理,所以只能直接找这些UA的交集做处理了,直接把UA匹配MSIE的就给封了,一般说来开源爱好者是不会使用IE的,在页面上说明一下影响也是OK的。http段增加一个map,根据ua来创建一下agent变量,主要是为了在日志打出请求是否被屏蔽: map $http_user_agent $agent { default 'false'; ~*MSIE 'true'; } server段新增localtion location ~* \.iso$ { root /mnt/nas/mirrors/; index index.html index.htm; autoindex on; if ( $request_method ~* HEAD ) { access_log off; } if ($agent = 'true') { limit_rate 1k; return 200; } } 这样对应被屏蔽的请求直接返回200.发现更新了配置后流量大降,可以看出对于一些个人站长如果做好放盗链本身也能大大降低自己的带宽开销。

January 11, 2014 · 1 min · pm

tomcat的keepalive时间设置问题

前几天进行线上的压测,发现应用的性能比之前还降低了就进行了一些分析。应用的结构是基础的apache+mod_jk+jboss的模式。主要的原因是之前的很多默认参数设置不合理,比如jk的配置worker.list=localworker.local.type=ajp13worker.local.host=localhostworker.local.port=8001worker.local.lbfactor=50worker.local.cachesize=100 #当前配置大于每个进程的最多线程数50,需要减小worker.local.cache_timeout=600 #闲置连接的清理时间worker.local.socket_keepalive=1worker.local.recycle_timeout=300 # #作用和cachesize类似但是在non-cache 的时候也能用 11:17:02.983554 IP (tos 0x0, ttl 64, id 26914, off set 0, flags [DF], proto 6, length: 60) 127.0.0.1.47060 > 127.0.0.1.7001: S [tcp sum ok] 3713142601:3713142601(0) win 3276711:17:02.983570 IP (tos 0x0, ttl 64, id 0, off set 0, flags [DF], proto 6, length: 60) 127.0.0.1.7001 > 127.0.0.1.47060: S [tcp sum ok] 3721181851:3721181851(0) ack 3713142602 win 32767 13:05:37.104641 IP (tos 0x0, ttl 64, id 0, off set 0, flags [DF], proto 6, length: 60) 127.0.0.1.7001 > 127.0.0.1.47265: S [tcp sum ok] 2010311520:2010311520(0) ack 2018476636 win 3276713:05:45.476963 IP (tos 0x0, ttl 64, id 17630, off set 0, flags [DF], proto 6, length: 60) 127.0.0.1.47280 > 127.0.0.1.7001: S [tcp sum ok] 2021138150:2021138150(0) win 3276713:05:45.476981 IP (tos 0x0, ttl 64, id 0, off set 0, flags [DF], proto 6, length: 60) 127.0.0.1.7001 > 127.0.0.1.47280: S [tcp sum ok] 2016571274:2016571274(0) ack 2021138151 win 3276713:06:11.061661 IP (tos 0x0, ttl 64, id 48536, off set 0, flags [DF], proto 6, length: 52) 127.0.0.1.7001 > 127.0.0.1.47265: F [tcp sum ok] 1642:1642(0) ack 467 win 819213:06:17.641781 IP (tos 0x0, ttl 64, id 13753, off set 0, flags [DF], proto 6, length: 52) 127.0.0.1.7001 > 127.0.0.1.47280: F [tcp sum ok] 1642:1642(0) ack 467 win 8192

April 26, 2013 · 1 min · pm

apache配置双向ssl认证

一. CA自签 1.建立 CA 目录结构mkdir -p ./demoCA/{private,newcerts}touch ./demoCA/index.txtecho 01 > ./demoCA/serial# 生成 CA 的 RSA 密钥对openssl genrsa -des3 -out ./demoCA/private/cakey.pem 2048# 生成 CA 证书请求openssl req -new -x509 -days 3650 -key ./demoCA/private/cakey.pem -out careq.pem#复制一份证书cp cacert.pem ca.crt二.生成和签发服务器、客户端证书#修改openssl配置文件/etc/pki/tls/openssl.cnf设置好dir = /root/ssl/demoCA (生成CA的路径)# 生成服务器的 RSA 密钥对openssl genrsa -des3 -out server.key运行时会提示输入密码,此密码用于加密key文件(参数des3便是指加密算法,当然也可以选用其他你认为安全的算法.),以后每当需读取此文件(通过openssl提供的命令或API)都需输入口令.如果觉得不方便,也可以去除这个口令。去除key文件口令的命令:openssl rsa -in server.key -out server.key# 生成服务器证书请求openssl req -new -days 3650 -key server.key -out server.csr# 使用 CA 签发服务器证书openssl ca -in server.csr -out server.crt -days 3650也可以直接指定好根证书的和其私钥的路径openssl ca -in server.csr -out server.crt -cert ./demoCA/cacert.pem -keyfile ./demoCA/private/cakey.pem ...

March 9, 2013 · 1 min · pm

blog迁移记录

根据前面blog说的ec2的低级错误造成的重大损失后,马上也想到EC2也快过期了就单独新买一个VPS。今天上午折腾了一下终于把数据都迁移好了。其实迁移blog主要是把db数据备份好。然后图片文件什么都通通打包下来。我是把blog目录直接整体打包了(包括图片什么的)。DB数据的备份就是使用的tools.php?page=wp-db-backup进行的。之前是设置了每周备份发送到邮箱里。昨天马上又保存了一份在自己电脑上面。然后把blog目录直接打个tgz包放到新的机器上面。1.重新配置lnmp环境1.1安装mysqlaptitude install mysql-server mysql-client安装的时候会设置一下mysql的密码,自己记住就行。1.2安装php5-fpmaptitude install php5-fpm php5-mysql nginx-full/etc/php5/fpm/pool.d/www.conf修改user = www-datagroup = www-datalisten.owner = www-datalisten.group = www-datalisten = /var/run/php5-fpm.sock #我是监听的sock形式/etc/init.d/php5-fpm restart 1.3 nginx配置nginx.conf 里面改动比较小,加client_max_body_size 50m;#防止上传文件的时候超过大小keepalive_timeout 5; #把这个减小一点,主要是机器配置也不好。gzip on;#gzip什么的开启节省带宽,也能提高速度gzip_vary on;gzip_proxied any;gzip_comp_level 6;gzip_buffers 16 8k;gzip_http_version 1.1;gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;/etc/nginx/sites-enabled/default 修改的多些,因为我申请了IPV6的地址,所以装B一把也把V6的监听起来。server段先定义一下限流的zonelimit_req_zone $binary_remote_addr zone=gnuers:10m rate=30r/s;listen 80;listen [::]:80 ipv6only=on;location php直接这样改改,加了防止盗链什么的,还限制了访问的host。bash location ~ .php$ {if ( $host !~* blog.gnuers.org ){rewrite ^ https://www.google.com permanent; }fastcgi_split_path_info ^(.+.php)(/.+)$; # NOTE: You should have “cgi.fix_pathinfo = 0; " in php.ini## # With php5-cgi alone:# # With php5-fpm:fastcgi_pass unix:/var/run/php5-fpm.sock; fastcgi_index index.php; include fastcgi_params; fastcgi_intercept_errors on; fastcgi_buffers 1024 4k; fastcgi_buffer_size 64k; fastcgi_busy_buffers_size 128k; fastcgi_send_timeout 60; fastcgi_read_timeout 60; fastcgi_connect_timeout 60; }location ~* .(gif|jpg|png|swf|flv)$ {valid_referers none blocked blog.gnuers.org ; if ($invalid_referer) {rewrite ^ http://www.google.com/ permanent; }expires 20m; } 1.3导入DB mysqldump -h localhost -u root -p 输入密码后登陆mysql,create database wordpress; use wordpress; set names utf8; #一定记得加这个,我之前么有加这个直接 mysql -h localhost -u root -pxxxxx wordpress#后中文乱码 source wordpress_wp_backup.sql ; ...

March 9, 2013 · 1 min · pm

apache的参数调整

apache+jboss是公司应用的基本结构。但是很多参数一直没有调整过。之前做个一些调优,把很多关键的参数看了一下,单独注释了。Timeout 180 #Timeout主要是定义了在处理一个请求时的多种超时时间,默认是300s。我们需要关注意的主要是2个。#一个是当读缓冲区为空时,等待client段发送一个包的超时时间。另外就是当发送缓冲区满的时候,#向客户端发送一个包后的等待确认时间。Timeout与单次请求的完成总时间毫无关系。KeepAlive On #是否启用KeepAlive,由于应用放spanner后端,开启后可以使得spanner能和应用保持持续的连接,提高一定性能。MaxKeepAliveRequests 100 #单个KeepAlive的连接能处理的最大请求数,可以适当调高,提高单个连接复用的效率。KeepAliveTimeout 3 #单个keepalive的连接在指定时间内如果没有请求,就进行回收。 StartServers 10 #初始的工作进程数量ServerLimit 50 #工作进程的最大数量MaxClients 2500 #最大的并发访问数量,不能超过ServerLimit*ThreadsPerChildMinSpareThreads 50 #最小的闲置线程数MaxSpareThreads 200 #最大的限制线程数ThreadsPerChild 50 #每个进程的最大线程数,需要注意32位的系统单个进程的能启动的线程数小于384.MaxRequestsPerChild 10000 #每个进程能处理的最大请求数。 mod_jk(Apache Tomcat) worker.list=local #定义worker的名称,如果有多个可以用逗号隔开(多个时候就是一个apache对多个tomcat做负载均衡)# 对于每个worker的属性定时使用这样的模式: worker..=worker.local.type=ajp13 #定义协议名称worker.local.host=localhost #因为是连本地的jboss,所以直接写localhost就行。worker.local.port=7001 #本地tomcat ajp的端口worker.local.lbfactor=50 #单个worker的权重,在有多个worker做负载均衡的时候此项才会有意义worker.local.cachesize=100 #单个进程对后端的连接被当初一个连接池对待,每个进程的链接池的连接数上限。需要注意最好不要超过apache里每个进程的线程数worker.local.cache_timeout=600 #当cachesize里连接池内的连接在关闭前被保留的时间。worker.local.socket_keepalive=1 #在apache和后tomcat间启用tcp的KEEP_ALIVE属性,主要是在当tomcat和jk直接有防火墙的时候会把不活动的连接关闭掉,此时可以通过设置此选项。worker.local.recycle_timeout=300 #作用其实和cache_timeout类似,但是在non-cache模式下也能使用。#当某个请求不在一定时间内不活跃后,告诉apache关闭该ajp连接,降低此值能大大减少后端tomcat的负担。 贴一个自己改过的配置:``` Timeout 10KeepAlive OnMaxKeepAliveRequests 1000KeepAliveTimeout 5 StartServers 10ServerLimit 50MaxClients 2500MinSpareThreads 50MaxSpareThreads 200ThreadsPerChild 50MaxRequestsPerChild 10000 workers.properties:# mod_jk(Apache Tomcat) worker.list=local worker.local.type=ajp13worker.local.host=localhostworker.local.port=7001worker.local.lbfactor=50worker.local.cachesize=25worker.local.cache_timeout=15worker.local.socket_keepalive=1worker.local.recycle_timeout=10

January 6, 2013 · 1 min · pm

tcp传输时影响性能的几个常见点

其实都是摘自TCP/IP详解和HTTP权威指南上面的。 1.http事务的时延主要是指我们要发起一个请求,需要先进行dns查询,然后对对应的IP:PORT发起请求。整个过程总每个环境都可能造成时延,比如dns查询,连接建立,服务器响应,请求和响应报文的大小。2.TCP三次握手。连接建立的三次握手也比较耗时,尤其是client和server相隔很远的时候物理距离造成的光传播时间本来就长,而且可能网络之类不佳造成重传等等都可能使得连接的建立耗时很久。对于返回内容比较少的情况下,连接建立时间占整体时间的比例会相对较大。3.延迟确认简单地说server向client连续发了几个组的数据,client其实不会直针对每个组都去发ACK确认,而是会在收到第一组数据后启动延迟定时器,过100-200ms再看看现在收到的所有组有那些,能连续组装起来的,就直接把最大的序号的组确认一下就OK了。4.TCP慢启动TCP的慢启动本来是为了避免快的发送方到慢的接受方这样的情况。所有每个连接连接后,开始发送的数据量比较小,比如一个分组,加入对方收到好ACK确认了,那么下次就直接发2个分组的数据,以此类推。因此新的连接比已经完成“调谐”的连接要慢一些,如果双方是持续连接(keepalive),那么效果就会比较好。5.Nagle算法与TCP_NODELAYnagle算法本来是为了避免每次发一个小的分组,造成网络性能非常差。Nagle算法要求一个TCP连接上最多只有一个未被确认的完成的小分组,但因为确认过程本身是由延迟定时器(100-200ms)来完成所以可能会造成额外的延迟。一般来说nagle算法会在对方确认的越快就会发送的最快,比较自适应。但是如果是类似telnet这种远程登录操作,或者是X系统里面鼠标的一个移动,那们都是希望能尽量实时,不要延迟,基本都会选择TCP_NODELAY选项关闭nagle算法。6.TIME_WAIT累计和端口耗尽。每个socket其实是由``` 源ip:源port,目标IP,目标port 当然,假如后面有很多机器,那么因为目标IP不同,实际情况会好些。

December 25, 2012 · 1 min · pm

nginx代理服务器的keepalive引发的思考

使用一个nginx做全局的代理负载均衡集群时遇到了一点问题。主要是前面的nginx集群机器很多(M个),每个nginx机器的进程也很多(N个),然后设置的keepalive数量和upstream里的机器数量相同。 这个时候如果后端机器的连接数限制比较小就杯具了,平时每个后端机器的长链接数差不多是MN +XX ,因此链接的利用率(XX)/(MN+XX) 。当前面的机器和单机进程数很多的时候链接的利用率就会非常低。造成健康检测时后端的机器检查失败,直接被踢掉了,引发雪崩效应。 这个时候如果后端的应用不改,那么唯一的2种方案: 1、改成短链接。可能整体的响应时间有所增加。2、适当降低keepalive的值,但是降低的太多会使得和短链接差不多的效果。很难定量的衡量这个值的最佳性,只能不断测试。 其实在apache的mod_jk模块里也是统一存在这样的问题``` Timeout 180KeepAlive OnMaxKeepAliveRequests 1000KeepAliveTimeout 360 StartServers 10ServerLimit 50MaxClients 1500MinSpareThreads 50MaxSpareThreads 200ThreadsPerChild 50MaxRequestsPerChild 10000 如果前面的很容易造成的情况是apache的jk把后端tomcat的链接数(400)撑爆了,但是实际上很多链接又闲着。主要是每个进程的信息是独立的,每个进程最多能有100个连接,整体的量就很难控制,尤其是上面这个空闲连接的回收时间设置的不合理。实际测试就是把这个回收的时间缩短,改成1,然后把cachesize降低到50 效果就好了很多。

November 30, 2012 · 1 min · pm

nginx代理测试

今天主要是还原一个线上的问题,自己搞了几个机器配置了一下nginx模拟做代理时后端服务器速度跟不上的问题。基本的结构如下 client —->nginx(proxy)—nginx server(limit rps 400/s) 因为我总的就3个机器,所以后端的nginx server里面配置的是 limit_conn_zone $binary_remote_addr zone=connzone:10m; limit_req_zone $binary_remote_addr zone=reqzone:10m rate=400r/s; server {listen 1081; server_name localhost; keepalive_requests 1000; 简单的对比测试了一下后端限速和不限速的情况。当后端不限速的时候压测时代理proxy 的load非常高,单个核的机器CPU使用率能到100%,usr,sys,soft各占了30%左右,但是后端服务器的load比较低,只有20%左右。当后端机器限速的时候proxy上会出现大量的503,并且load还是很高,基本和前面的相同,但是后端的服务器load也会比较高,在30%–80%间波动。检查后端服务器的日志可以发现很多健康检测的请求被置为了503,也就是存在服务器被踢掉的情况。 另外顺便测试了一下apache的配置,之前的woker的配置``` Timeout 180KeepAlive OnMaxKeepAliveRequests 100KeepAliveTimeout 360 StartServers 10ServerLimit 50MaxClients 1500MinSpareThreads 50MaxSpareThreads 200ThreadsPerChild 50MaxRequestsPerChild 10000

November 21, 2012 · 1 min · pm

使用stunnel进行ssl加密

stunnel是个功能很简单的软件,就是进行ssl加密。可以帮助我们把http加密为https,也可以对普通的tcp链接进行ssl加密。stunnel的安装非常简单,就想详细写了。在centos下是只用用yum安装的,debian下就直接aptitude安装了。使用stunnel的配置如果不对客户端进行证书校验的话那么主要是2方面的配置。 1.配置ssl证书。stunnel配置证书有两种方式。老的方式是使用http://www.stunnel.org/static/stunnel.html介绍的先把key放最前面,然后依次放证书链。类似 -----BEGIN RSA PRIVATE KEY----- [encoded key] -----END RSA PRIVATE KEY----- [empty line] -----BEGIN CERTIFICATE----- [encoded certificate] -----END CERTIFICATE----- [empty line] 这种形式,如果服务器证书不是由根CA签发的,那么就需要类型nginx配置证书链那样把后面中间证书都逆序依次追加在后面。每个证书之间预留一个空行(不过我自己测试时不需要空行也是可以的)。这时的配置文件如下: ; Sample stunnel configuration file by Michal Trojnara 2002-2006; Some options used here may not be adequate for your particular configuration; Please make sure you understand them (especially the effect of chroot jail) ; Some debugging stuff useful for troubleshooting;debug = 7output = stunnel.log ; Use it for client mode;client = yes ...

July 14, 2012 · 2 min · pm