一、Nginx学习
1.安装
1)下载nginx centos系统
wget http://nginx.org/download/nginx-1.6.2.tar.gz
2)安装pcre库
pcre支持rewrite库
命令:yum install pcre-devel –y(-y 对所有问题都回答yes)
3)隐藏nginx版本号
vimsrc/core/nginx.h
修改其中的版本号为空,修改名称为自定义
4)预编译
./configure--user=www --group=wwww --prefix=/usr/local/nginx--with-http_stub_status_module --with-http_ssl_module
常用参数
--prefix指定安装根目录
–sbin-path可执行文件目录,默认/sbin/nginx
–conf-path配置文件目录,默认/conf/nginx.conf
–pid-pathpid文件的存放路径,默认存放在/logs/nginx.pid
–error-log-path设置主请求的错误、警告、诊断的日志文件的名称,默认/logs/access.log
–http-log-path设置HTTP服务器的主请求的日志文件的名称,默认/logs/access.log,。该名称也可以在nginx.conf配置文件中通过access_log指令更改
–user设置工作进程使用的非特权用户的用户名,默认为nobody
–group设置工作进程使用的非特权用户组的名称,默认组名和–user的名称一致。安装完成后可以在nginx.conf配置文件中通过user指令指定
加载模块
–with-select-module、–without-select-module 启用或者禁用一个模块
–without-http_rewrite_module禁止构建允许HTTP服务器重定向和变更请求URI的模块。构建和运行该模块需要PCRE库
–without-http_proxy_module禁用HTTP服务器代理模块
–with-http_ssl_module 启用添加HTTPS协议支持到HTTP服务器的模块,该模块默认不启用。构建和运行该模块需要OpenSSL库
–with-pcre=path设置PCRE库的路径,该库需要从PCRE网站下载
–with-zlib=path设置zlib库的路径,ngx_http_gzip_module模块需要该库
–without-http_gzip_module禁用构建gzip压缩模块。构建和运行该模块需要zlib库
–with-ld-opt加入第三方链接时需要的参数
–with-debug将nginx需要打印debug调试级别日志的代码编译进nginx
5)编译
make
6)安装
makeinstall
7)检查nginx是否正确
/usr/local/nginx/sbin/nginx–t 返回successful即为正确
8)常用命令
netstat–ntl 检查已启用端口
pkillnginx 杀死nginx的进程
9)启动nginx
/usr/local/nginx/sbin/nginx
10)访问
占用80端口,直接输入ip查看
2.nginx常用
1)nginx中主线程只有一个,工作线程的数量与nginx.conf中配置的worker_processer有关.;
Nginx的发布目录在./html/index.html中,里边有默认目录
2)nginx平滑重启
/usr/local/nginx/sbin/nginx -s reload
停止
pkill -9 nginx
./usr/local/nginx/sbin/nginx–s stop
查看configure 的参数
./nginx–V
查看ngxin版本
./nginx -v
n 这部分命令不靠谱
完美停止nginx
kill–QUIT `cat /usr/local/nginx/logs/nginx.pid `
快速停止nginx
kill–TERM `cat /usr/local/nginx/logs/nginx.pid `
或者
kill–INT `cat /usr/local/nginx/logs/nginx.pid
完美停止工作进程(主要用于平滑升级)
kill –WINCH `cat /usr/local/nginx/logs/nginx.pid `
3)ngxin升级或降级
从新下载解压包;
执行configure时候参数要与原版本参数一样;
执行make操作;
重命名执行文件mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old;
从编译文件中拿取nginx
cp /root/nginx-1.6.2/objs/nginx /usr/local/nginx/sbin/
平滑重启升级
kill-USR2 `cat /usr/local/nginx/logs/nginx.pid`
3.nginx配置文件
见nginx.config文件
4.动静分离框架
1)查询端口号是否被占用 netstat-ntl | grep 9090
5.Linux内核优化
当linux下Nginx达到并发数很高,TCP TIME_WAIT套接字数量经常达到两、三万,这样服务器很容易被拖死。事实上,我们可以简单的通过修改Linux内核参数,可以减少Nginx服务器 的TIME_WAIT套接字数量,进而提高Nginx服务器并发性能。
vi /etc/sysctl.conf
net.ipv4.tcp_max_tw_buckets = 6000
timewait的数量,默认是180000。
net.ipv4.ip_local_port_range = 1024 65000
允许系统打开的端口范围。
net.ipv4.tcp_tw_recycle = 1
启用timewait快速回收。
net.ipv4.tcp_tw_reuse = 1
开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接。
net.ipv4.tcp_syncookies = 1
开启SYN Cookies,当出现SYN等待队列溢出时,启用cookies来处理。
net.core.somaxconn = 262144
web应用中listen函数的backlog默认会给我们内核参数的net.core.somaxconn限制到128,而Nginx内核参数定义的NGX_LISTEN_BACKLOG默认为511,所以有必要调整这个值。
net.core.netdev_max_backlog = 262144
每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目。
net.ipv4.tcp_max_orphans = 262144
系统中最多有多少个TCP套接字不被关联到任何一个用户文件句柄上。如果超过这个数字,孤儿连接将即刻被复位并打印出警告信息。这个限制仅仅是为了防止简单的DoS攻击,不能过分依靠它或者人为地减小这个值,更应该增加这个值(如果增加了内存之后)。
net.ipv4.tcp_max_syn_backlog = 262144
记录的那些尚未收到客户端确认信息的连接请求的最大值。对于有128M内存的系统而言,缺省值是1024,小内存的系统则是128。
net.ipv4.tcp_timestamps = 0
时间戳可以避免序列号的卷绕。一个1Gbps的链路肯定会遇到以前用过的序列号。时间戳能够让内核接受这种“异常”的数据包。这里需要将其关掉。
net.ipv4.tcp_synack_retries = 1
为了打开对端的连接,内核需要发送一个SYN并附带一个回应前面一个SYN的ACK。也就是所谓三次握手中的第二次握手。这个设置决定了内核放弃连接之前发送SYN+ACK包的数量。
net.ipv4.tcp_syn_retries = 1
在内核放弃建立连接之前发送SYN包的数量。
net.ipv4.tcp_fin_timeout = 1
如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间。对端可以出错并永远不关闭连接,甚至意外当机。缺省值是60秒。2.2 内核的通常值是180秒,你可以按这个设置,但要记住的是,即使你的机器是一个轻载的WEB服务器,也有因为大量的死套接字而内存溢出的风险,FIN- WAIT-2的危险性比FIN-WAIT-1要小,因为它最多只能吃掉1.5K内存,但是它们的生存期长些。
net.ipv4.tcp_keepalive_time = 30
当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时。
6.nginx的五种upstream负载均衡机制
1)轮询
默认机制,每个请求按照顺序逐一分配到不同服务器,如果后台某台服务器down掉,会自动剔除,待恢复后重新调用。
2)权重
后端性能不一致时候
3)ip_hash
用于解决后端session不一致时候
4)fair
根据后台响应时间分配,相应时间短的优先分配
5)url_hash
调用静态页时候可以使用url_hash,应用缓存
7.日志分割与格式
1)格式定义
log_format main '$remote_addr - $remote_user[$time_local] "$request" '
'$status $body_bytes_sent"$http_referer" '
'"$http_user_agent""$http_x_forwarded_for"';
$remote_addr$http_x_forwarded_for 记录客户端IP地址
$remote_user记录客户端用户名
$request记录请求的url和HTTP协议
$status记录请求状态 200 301 302 404 500
$body_bytes_sent发送给客户端的字节数,不包括响应头的大小
$bytes_sent发动给客户端的总字节数
$connection_requests当前通过一个连接获得的请求数量
$http_referrer 记录从哪个url跳转过来的
$http_user_agent记录客户端浏览器信息
$request_length请求的长度(包括请求头、请求行、请求正文)
2)分隔
用脚本。。。。
8.常用命令
cataccess.log | wc –l 显示行数
du–sh access.log 显示大小
cataccess.log|more 显示一屏幕
awk‘{print $1}’ access.log 查看每行第一个空格之前的内容,目前配置显示ip
awk‘{print $1}’ access.log|uniq –c 显示不重复ip,及每个ip调用次数
awk‘{print $1}’ access.log | sort | uniq –c |sort –nr |head -10 显示访问量最高的十个ip
wc –l 显示行数
uniq–c 去重
head-10 显示前10行
grep keyword 查询关键字,*为通配符
sed –n “/time1/,/time2/”paccess.log 查询时间段内的日志 time格式:
lsof –i:3310 查询3310端口服务
netstat –tnl 查询所有已启动端口
curl url 访问url并返回页面代码
9.nginx防盗链
location模块中添加
location~* \.(gif|jpg|png|swf|flv)$ {
valid_referesnone blocked *.test.com
if($valid_referes){
Return403;
}
root html/b;
expires 30d;
}
设置只能从test.com这个网站调用,valid_referes是获取头信息,如果获取不到,返回403页面
10.错误分析
200第一次访问
301永久重定向
302临时重定向
304缓存返回
400表示网站域名未找到
404表示页面路径未找到
499请求过于频繁,nginx内置的安全策略拦截并返回的
502、503、504 网关超时,找到域名,但是访问端口号超时
11.缓存服务框架
configure时候添加缓存模块,nginx的缓存采用硬盘文件缓存,所以在http模块中需要设置缓存路经过,并在具体的server中指定需要缓存,清理缓存的话可以直接删除该缓存目录。
12.openresty开始
1)高性能的两个因素:缓存、异步非阻塞
内存>SSD>机械硬盘
本机>网络
进程内>进程外
2)高性能开发
Nginx中高性能模块nginx c module,开发成本高,要求高
3)简介
Openresty采用LuaJIT,其与lua本身区别不大,openresty是nginx与LuaJIT的结合。其性能接近c module,甚至超过
4)对比
Node.js
使用回调来实现异步非阻塞,不符合开发习惯
Python
3.4之后加入异步IO,3.5引入协程,版本跨度大
Golang
异步不太完美,但发展非常快
SystemTap
性能分析工具,不重启服务也能定位bug,
Baas
后端即服务,适用于小公司
13.搭建
根据官网的安装页提示
./configure后边跟具体系统的尾部参数
sudomake && make install
lua编译
location / {
default_type text/html;
content_by_lua '
ngx.say("hello, world
")
';
}
或者引用配置文件
content_by_lua_fileurl 引用xxx.lua的配置文件
ngxlua 的api网址
https://www.nginx.com/resources/wiki/modules/lua/#lua-code-cache
《openresty最佳实践》是视频作者在github上开源的一本书。
配置文件一般使用缓存,所以更改不会生效,可以设置lua_code_cache off;但这样只适用于开发调试阶段,生产环境一般不用。
14.openresty的mysql和redis支持
15.openresty的缓存和粽子吃
1)shared_dict缓存
多线程公用缓存,有抢锁问题,需要提前设置内存占用大小
2)lurCache
每个线程单独使用,需要设置key-value的上限
3)比较
lurCache保存的是热点数据,但是多线程的情况下内存占用可能比较大,而且api只有get,set,delete三种方法,shared_dict占用的内存空间相对较小,但是多线程访问有抢锁,最好针对不同业务创建不同shared_dict
16.openresty的缓存ab测试性能与分析
1)命令:ab –n 1000000 –c 100 –k http:127.0.0.1/get_value
100个终端模拟请求1000000次,查看qps
采用shared_dict,开了缓存查询redis比直接查询redis快了差不多一倍,而查询mysql的话会快更多
qps一秒访问次数
2)缓存失效风暴
ex:缓存设置失效时间100s,做压测时候,每100s会出现一个压测的峰值,因为100s时候所有线程都会获取不到缓存值,并且都去查询数据库/redis,造成压力,查询出来后放
入缓存,又会恢复平静。
lua-resty-lock现成的锁机制
16.ffi
ffi调用其他语言实现效果,可以查看lualib/resty里的lua文件,random.lua 比较简单;
17,第三方模块
使用http模块
google搜索resty http
选择模块的原则 star比较多 更新频繁 更新人数多
githua上下载lua文件后,放入resty下 用require引入
18.子查询
capture
在一个location中调用另外一个location,例子:
Location /lua
content_by_lua ‘
local res = ngx.location.capture
(“/some_other_location”)
if res.status == 200 then
Ngx.print(res.body)
end’;
}
capture时候并非使用http调用,而是类似于c函数,开销比较小。
采用并发访问res1,res2,res3,响应时间是其中最慢的那个,对于同一个页面多个ajax可以采用这种方式,因为ajax采用http多次访问,而openresty的方式更加方便,只调用一次http,响应时间也不增加
res1,res2,res3 = ngx.location.capture_multi{
{“/foo”,{args = “a=3&b=4”}},
{“/bar”},
{“/baz”,{method=ngx.HTTP_POST,body=”hello”}},
}
19.执行阶段
nginx有十几个执行阶段,openresty简化成六七个。
set_by_lua流程分支判断,判断初始化
rewrite_by_lua转发、重定向、缓存等功能
access_by_luaip准入、接口权限、合法性、防火墙等功能、请求解密
content_by_lua内容生成
header_filter_by_lua过滤请求头、增加头部信息
body_filter_by_lua对应答的处理,比如处理请求都改成小写,应答报文加密
log_by_lua记录日志,记录到本地或推送到远端日志服务器