Nginx笔记大全

背景

Nginx一个具有高性能的HTTP和反向代理的web服务器。

目前负载均衡技术中的主流方案,是一个轻量级的高性能HTTP反向代理服务器,支持TCP、UDP、SMTP、HTTPS等。基于多路复用模型构建出的产物,理论上单节点同时支持5W并发连接。如动静分离、资源压缩、缓存配置、IP黑名单、高可用保障等高级特性

nginx优点

  • 速度更快、并发更高:采用了多进程和I/O多路复用(epoll)的底层实现。
  • 配置简单,扩展性强:模块组成。
  • 高可靠性:多进程,一个master主进程和多个worker进程,每个worker之间相互独立提供服务,并且主进程可以在某个worker进程出错时,快速拉起新的worker进程提供服务。
  • 热部署:在Nginx不停止情况下,对Nginx进行文件升级、更新配置和更换日志文件。
  • 成本低、BSD许可证:

Nginx的功能特性及常用功能

基本HTTP服务

可以作为HTTP代理服务器和反向代理服务器,支持通过缓存加速访问,可以完成简单的负载均衡和容错,支持包过滤功能,支持SSL等。

  • 处理静态文件、处理索引文件以及支持自动索引;
  • 提供反向代理服务器,并可以使用缓存加上反向代理,同时完成负载均衡和容错;
  • 提供对FastCGI、memcached等服务的缓存机制,,同时完成负载均衡和容错;
  • 使用Nginx的模块化特性提供过滤器功能。Nginx基本过滤器包括gzip压缩、ranges支持、chunked响应、XSLT、SSI以及图像缩放等。其中针对包含多个SSI的页面,经由FastCGI或反向代理,SSI过滤器可以并行处理。
  • 支持HTTP下的安全套接层安全协议SSL.
  • 支持基于加权和依赖的优先权的HTTP/2

SSI 是一种类似于 ASP 的基于服务器的网页制作技术。将内容发送到浏览器之前,可以使用“服务器端包含(SSI)”指令将文本、图形或应用程序信息包含到网页中。例如,可以使用 SSI 包含时间/日期戳、版权声明或供客户填写并返回的表单。对于在多个文件中重复出现的文本或图形,使用包含文件是一种简便的方法。将内容存入一个包含文件中即可,而不必将内容输入所有文件。通过一个非常简单的语句即可调用包含文件,此语句指示 Web 服务器将内容插入适当网页。而且,使用包含文件时,对内容的所有更改只需在一个地方就能完成。因为包含 SSI 指令的文件要求特殊处理,所以必须为所有 SSI 文件赋予 SSI 文件扩展名。默认扩展名是 .stm、.shtm 和 .shtml

高级HTTP服务
  • 支持基于名字和IP的虚拟主机设置
  • 支持HTTP/1.0中的KEEP-Alive模式和管线(PipeLined)模型连接
  • 自定义访问日志格式、带缓存的日志写操作以及快速日志轮转。
  • 提供3xx~5xx错误代码重定向功能
  • 支持重写(Rewrite)模块扩展
  • 支持重新加载配置以及在线升级时无需中断正在处理的请求
  • 支持网络监控
  • 支持FLV和MP4流媒体传输
邮件服务
  • 支持IMPA/POP3代理服务功能
  • 支持内部SMTP代理服务功能

Nginx环境准备

Nginx的官方下载网站为http://nginx.org/en/download.html,源码地址http://nginx.org/download/

  1. 确认centos的内核:必须是2.6(支持epoll)以上。uname -a
  2. 确认关闭防火墙:systemctl stop/disable firewalld
  3. 确认停用selinux:sestatus查看状态;SELINUX=disabled 关闭;/etc/selinux/config

Nginx安装方式

通过源码安装依赖的类库
  • GCC编译器:Nginx是C语音编写的程序,运行需要一个编译工具(yum install -y gcc;gcc --version)。
  • PCRE库:正则表达式库,Rewrite模块和核心模块都会用到正则表达式语法。yum install -y pcre pcre-devel;rpm -qa pcre pcre-devel来查看是否安装成功。
  • zlib库:压缩算法。yum install -y zlib zlib-devel 。
  • OpenSSL:可以在Internet上提供秘密性传输,其目标是保证两个应用间通信的保密性和可靠性。yum install -y openssl openssl-devel

yum install -y gcc pcre pcre-devel zlib zlib-devel openssl openssl-devel进行全部安装

Nginx源码简单安装
mkdir -p /usr/local/nginx/core
cd /usr/local/nginx/core
wget http://nginx.org/download/nginx-1.20.1.tar.gz
tar -xzf nginx-1.20.1.tar.gz
cd ./configure
make
make install
yum 安装
sudo yum install -y yum-utils ## 安装过忽略
vim /etc/yum.repos.d/nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/ $basearch/ 
gpgcheck=1  
enabled=1  
gpgkey=https://nginx.org/keys/nginx_signing.key 
module_hotfixes=true  

[nginx-mainline] 
name=nginx mainline repo 
baseurl=http://nginx.org/packages/mainline/centos/$re leasever/$basearch/ 
gpgcheck=1 
enabled=0 
gpgkey=https://nginx.org/keys/nginx_signing.key 
module_hotfixes=true

yum list | grep nginx  ##查看是否安装成功
yun install -y nginx
源码复杂安装

复杂对于简单区别就是编译可以指定参数 (详情见附录A)。

  • PATH:是和路径相关的配置信息
  • with:是启动模块,默认是关闭的
  • without:是关闭模块,默认是开启的

–prefix=path 安装目录,默认值/usr/local/nginx;
–sbin-path=path执行程序路径,默认值$prefix/sbin/nginx ;
–modules-path=path模块安装目录,默认$prefix/modules;
–conf-path=path配置文件,默认prefix/conf/nginx.conf;
–error-log-path = 指向错误日志目录;
–pid-path= 指向 pid 文件(nginx.pid)
–lock-path= 指向 lock 文件(nginx.lock)(安装文件锁定,防止安装文件被别人利用,或自己误操作。)
–user= 指定程序运行时的非特权用户; –group= 指定程序运行时的非特权用户组
–builddir= 指向编译目录
http-log-path;pid-path=paht默认prefix/logs/nginx.pid;

./configure --prefix=/usr/local/nginx \ --sbin-path=/usr/local/nginx/sbin/nginx \ --modules-path=/usr/local/nginx/modules \ --conf-path=/usr/local/nginx/conf/nginx.conf \ --error-log-path=/usr/local/nginx/logs/error.log \ --http-log-path=/usr/local/nginx/logs/access.log \ --pid-path=/usr/local/nginx/logs/nginx.pid \ --lock-path=/usr/local/nginx/logs/nginx.lock 

./configure --with-http_stub_status_module --with-http_ssl_module --with-stream
--with-select_module、--without-select_module、 --with-poll_module、--without-poll_module

 ./configure --add-module=/path/to/nginx_tcp_proxy_module    //代理
 
卸载nginx
./nginx -s stop
rm -rf /usr/local/nginx
make clean

Nginx启停命令

Nginx服务的信号控制

USR2信号给master进程,告诉它进程要平滑升级,会重新开启对应的master和work进程,整个系统有两个master。旧的PID被记录在nginx.pid.oldbin文件中,接着再次发送quit信号给旧的master,让其处理完请求后再进行关闭。
kill -USR2 PID / kill -USR2 cat /usr/local/nginx/logs/nginx.pid

TERM/INT:立即关闭整个服务;QUIT:优雅关闭;HUP:重读配置文件;WINCH:给work进程发送quit指令。

命令行控制(sbin)

nginx -s stop(term) ; quit(quit);reload(HUP)

Nginx版本升级和新增模块

例如:版本1.16.1升级到1.20.1
进入1.16.1安装目录;./configure;make && make install编译与安装
进入1.20.1安装目录;./configure;make

使用信号进行升级
  • 将1.16.1版本的sbin目录下的nginx进行备份
cd /usr/local/nginx/sbin 
mv nginx nginxold
  • 将1.20.1安装目录编译后的objs目录下的nginx文件,拷贝到原来/usr/local/nginx/sbin目录下
cd ~/nginx/core/nginx-1.20.1/objs 
cp nginx /usr/local/nginx/sbin
  • 发送信号usr2给1.16.1版本对应的master进程;发送信号quit给1.16.1版本对应的master进程
    kill -QUIT more /usr/local/logs/nginx.pid.oldbin
使用安装目录的make命令完成升级

前两步一样;然后进入1.20.1目录(安装目录),执行make upgrade。

核心配置文件结构

  • events块:设置nginx服务器与用户的网络连接,决定性能。
  • http块 :代理、缓存、日志记录、第三方模块配置。

http里面中 server块是配置和虚拟主机相关的内容。location块是接收请求字符串与location后面的值进行匹配,对特定请求进行处理。 http->server->location (父含有多个孩子)

全局块
  • user:配置worker进程的用户和用户组(可以把文件放到/home/用户名/html 才有访问权限)
  • work process:master_process on|off(指定是否开启工作进程);worker_processes num/auto(并发处理,建议数值与cpu的内核数一致);daemon on|off(守护式进程,不会随着终端关闭而停止);pid file(存放进程的id);error_log file;include file(引入其他配置文件);

debug|info|notice|warn|error|crit|alert|emerg,翻译过来为调试|信 息|通知|警告|错误|临界|警报|紧急,这块建议大家设置的时候不要设置成info以下的等级,因为会带来大量的磁盘I/O消耗,影响Nginx的性能。

events块
events {
	accept_mutex on|off; #设置网络连接序列化(防止多个进程对连接的争抢,一个个唤醒接收)
	multi_accept off|on; #设置是否允许同时接收多个网络连接
    worker_connections 1024; #最大连接数。不仅仅包括和前端用户建立的连接数,而是包括所有可能的连接数
    use method; #默认根据操作系统。select/poll/epoll/kqueue等。内核2.6 可以用epoll
}
http块

某些接口的时候需要返回指定的文本字符串或者json字符串,如果逻辑非常简单或者干脆是固定的字符串,那么可以使用nginx快速实现,这样就不用编写程序响应请求了,可以减少服务器资源占用并且响应性能非常快。

location /get_json{ 
	default_type application/json; 
	return 200 '{"name":"TOM","age":18}'; 
}
http {
    charset                utf-8;
    sendfile               on;
    tcp_nopush             on;
    tcp_nodelay            on;
    server_tokens          off;
    log_not_found          off;
    types_hash_max_size    2048;
    types_hash_bucket_size 64;
    client_max_body_size   16M;
    
    # 注意如果启用 SSI,那么 Last-Modified 头和 Content-Length 头不会传递
    # 建议写道location里面 location ~* \.shtml${ ssi on; ssi_types text/shtml; ssi_value_length 1024}
    ssi [ on | off ]
    
    # MIME 默认
    include                mime.types;
    default_type           application/octet-stream;
    
    # Logging
    #正向代理,服务器收到是代理IP地址
    #client send request=>clientIp=192.168.1.1 serverIp=>192.168.1.200
    log_format client 'client send request=>clientIp=$remote_addr serverIp=>$host';
    log_format  server1 '===>server1 access log';
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log             /var/log/nginx/access.log main;
    error_log              /var/log/nginx/error.log warn;

	sendfile     on;  #提高Nginx处理静态资源的性能
	keepalive_timeout 65; #用来设置长连接的超时时间,默认75s
	keepalive_requests 100; #设置一个keep-alive连接使用次数,默认100
	include /XXX/XXX/conf.d/server/*.conf; #如nginx_gzip.conf
}

使用keepalive模式,可以告诉服务器端在处理完 一个请求后保持这个TCP连接的打开状态,若接收到来自这个客户端的其 他请求,服务端就会利用这个未被关闭的连接,而不需要重新创建一个新 连接,提升效率,但是这个连接也不能一直保持,这样的话,连接如果过 多,也会是服务端的性能下降,这个时候就需要我们进行设置其的超时时 间

详细参数说明参考

server块和location块

server1.conf

server{ 
	#配置监听端口和主机名称 
	listen 8081; 
	# 虚拟主机的域名,可以写多个域名
	server_name localhost; 
	#配置请求处理日志存放路径 
	access_log /home/www/myweb/server1/logs/access.log server1; 
	#配置错误页面 
	error_page 404 /404.html; 
	#配置处理/server1/location1请求的location 
	location /server1/location1{ 
		root /home/www/myweb; 
		index index_sr1_location1.html; 
	} 
	#配置处理/server1/location2请求的location 
	location /server1/location2{ 
		root /home/www/myweb; 
		index index_sr1_location2.html; 
	} 
	#配置错误页面转向 
	location = /404.html { 
		root /home/www/myweb; 22 index 404.html; 
	 } 
}

服务操作问题

配置成系统服务
  1. 在/usr/lib/systemd/system目录下添加nginx.service,内容如下:
[Unit] 
Description=nginx web service 
Documentation=http://nginx.org/en/docs/ 
After=network.target 

[Service] 
Type=forking 
PIDFile=/usr/local/nginx/logs/nginx.pid 
ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf 
ExecStart=/usr/local/nginx/sbin/nginx 
ExecReload=/usr/local/nginx/sbin/nginx -s reload 
ExecStop=/usr/local/nginx/sbin/nginx -s stop 
PrivateTmp=true 

[Install] 
WantedBy=default.target

chmod 755 /usr/lib/systemd/system/nginx.service
启动: systemctl start nginx
停止: systemctl stop nginx
重启: systemctl restart nginx
重新加载配置文件: systemctl reload nginx
查看nginx状态: systemctl status nginx
开机启动: systemctl enable nginx

命令配置到系统环境

vim /etc/profile
在最后一行添加 export PATH=$PATH:/usr/local/nginx/sbin 12

使之立即生效:source /etc/profile

日志切割
# vim nginx-log-rotate
/data/weblogs/*.log {
 nocompress
 daily
 copytruncate
 create
 notifempty
 rotate 7
 olddir /data/weblogs/old_log
 missingok
 dateext
 postrotate
 /bin/kill -HUP `cat /var/run/nginx.pid 2> /dev/null` 2> /dev/null || true
 endscript
}

# vim /etc/crontab 设置计划任务
59 23 * * * root ( /usr/sbin/logrotate -f /PATH/TO/nginx-log-rotate)

/data/weblogs/*.log 使用通配符时,/data/weblogs/目录下的所有匹配到的日志文件都将切割。如果要切割特定日志文件,就指定到该文件.

静态资源部署

静态资源即指在服务器端真实存在并且能直接拿来展示的一些文件,比如常见的html页面、css文件、js文件、图 片、视频等资源; 动态资源即指在服务器端真实存在但是要想获取需要经过一定的业务逻辑处理,根据不同的条件展示在页面不同这 一部分内容,比如说报表数据展示、根据当前登录用户展示相关具体数据等资源;

静态资源的配置指令

listen:127.0.0.1:8000;监听指定IP和端口(不写IP默认是本机)

server{ 
	#default_server属性是标识符,用来将此虚拟主机设置成默认主机。所谓的默认主机指的是如果没有匹配到对应的address:port,则会默认执行的。
	listen 8080 default_server;

server_name:设置虚拟主机服务名称。精准匹配、通配符(只能出现在首段或尾段)、正则表达式(~ 作为开始标记。如~^www.(\w+).com$以www开头,com结尾,任意字符匹配)

hosts:是一个没有扩展名的系统文件,可以用记事本等工具打开,其作用 就是将一些常用的网址域名与其对应的IP地址建立一个关联“数据库”,当 用户在浏览器中输入一个需要登录的网址时,系统会首先自动从hosts文 件中寻找对应的IP地址,一旦找到,系统会立即打开对应网页,如果没有 找到,则系统会再将网址提交DNS域名解析服务器进行IP地址的解析。
匹配执行顺序:exact_success -> wildcard_before_success -> wildcard_after_success -> regex_success -> default_server not found server!!

location:[ = | ~ | ~* | ^~ |@ ] uri{…}。/abc是以abc开头的;=/abc是精准匹配;~^/abc\w$ 用于表示当前uri中包含了正则表达式,并且区分大小写;~*^/abc\w$ 用于表示当前uri中包含了正则表达式,并且不区分大小写; ^~/abc 与/abc功能一致,不同是模式匹配就停止搜索其他模式了。
root:设置请求的根目录(root路径+location路径)。
index:设置网站的默认首页。
error_page:code uri;

	#指定具体跳转的地址
	error_page 404 http://www.itcast.cn;
	#指定重定向地址
	error_page 404 /50x.html; 
	error_page 500 502 503 504 /50x.html; 
	location =/50x.html{ 
		root html; 
	}
	#使用location的@符合完成错误信息展示
	error_page 404 @jump_to_error; 
	location @jump_to_error { 
		default_type text/plain; 
		return 404 'Not Found Page...'; 
	}
	#可选项=[response]的作用是用来将相应代码更改为另外一个
	error_page 404 =200 /50x.html; #当返回404时候,浏览器看到返回200状态码
静态资源优化配置语法

sendfile on:用于开启高效的文件传输模式。
tcp_nopush on:在senfile打开的状态下才会生效,主要提升网络包的传输效率。
tcp_nodelay on:该指令必须在keep-alive连接开启的情况下才生效,来提高网络包传输的’实时性’。

sendfile可以开启高效的文件传输模式,tcp_nopush开启可以确保在发送到客户端之前数据包已经充分“填满”, 这大大减少了网络开销,并加快了文件发送的速度。 然后,当它到达最后一个可能因为没有“填满”而暂停的数据包时,Nginx会忽略tcp_nopush参数, 然后,tcp_nodelay强制套接字发送数据。由此可知,TCP_NOPUSH可以与TCP_NODELAY一起设置,它比单独配置TCP_NODELAY具有更强的性能。

静态资源压缩实战

可以通过配置gzip来对静态资源进行压缩,相关的指令可以配置在http块、server块和location块中。
ngx_http_gzip_module模块; ngx_http_gzip_static_module模块; ngx_http_gunzip_module模块。
ngx_http_gzip_module模块

gzip on; #开启或关闭
gzip_types application/javascript; #根据响应页的MIME类型选择开启Gzip压缩功能;如是*号代表所有
gzip_comp_level 6; #压缩程度。默认1,程度越高越费时间
gzip_vary off|on; #是告诉接收方,所发送的数据经过了Gzip压缩处理
# gzip_buffers 32 4k|16 8k; #处理请求压缩的缓冲区的数量和大小(建议不设置采用系统默认)
gzip_disable "MSIE [1-6]\.";  #针对不同种类客户端发起的请求,选择性开启和关闭Gzip功能(排除一些明显不支持Gzip的浏览器);对IE6以下的版本不进行压缩。
# gzip_http_version:针对不同http协议版本,选择性开启和关闭功能(建议不设置)。
gzip_min_length 5k; #传输数据大小,来选择开启和关闭功能(如果要压缩的数据比较小的化,可能出现越压缩数据量越大的情况)。
gzip_proxied off; #设置是否对服务端返回的结果进行Gzip压缩(expired|no-cache|nostore|private|no_last_modified|no_etag|auth|any)

很多地方用到,可以单独放一个配置文件中,然后通过include指令加载nginx_gzip.conf

ngx_http_gzip_static_module模块
需要安装

cd /root/nginx/core/nginx-1.16.1 
make clean ;#清空之前编译的内容
./configure --with-http_gzip_static_module;
make ;#编译
mv objs/nginx /usr/local/nginx/sbin #编译后文件放到安装目录下的sbin
make upgrade  #更新命令

【Gzip和sendfile共存问题】:sendfile不经过用户进程,Gzip经过用户进程。

gzip_static on; #检查与访问资源同名的.gz文件,response中以gzip相关的header返回.gz文件的内容。
静态资源的缓存处理

浏览器缓存:成本最低的一种缓存实现;减少网络带宽消耗;降低服务器压力;减少网络延迟,加快页面打开速度。

header 说明
Expires 缓存过期的日期和时间
Cache-Control 设置和缓存相关的配置信息
Last-Modified 请求资源最后修改时间
ETag 请求变量的实体标签的当前值,比如文件的MD5值

Nginx笔记大全_第1张图片

# Nginx进行缓存相关设置
expires off; #-1不缓存;0最大值 ; 7d 7天过期
add_header name value [always]; #用来添加指定的响应头和响应值
deny all; #禁止下载
跨域问题解决

同源策略 :一种约定,是浏览器最核心也是最基本的安全功能(需要协议、域名、端口相同)。
跨域问题 : 不满足同源策略。

#在不同源的 location /{}内加上跨域报头
add_header Access-Control-Allow-Origin *; 
add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE;
静态资源防盗链

实现原理:头信息referer,告诉浏览器该网页是从哪个页面链接过来的。
valid_referrers:通过查看referer自动和valid_referers后面的内容进行匹配,匹配为0,不匹配为1,匹配过程中不区分大小写。

#location /images{ 特定目录images下所有资源
location ~*\.(png|jpg|gif){ 
	#none:如果header中referer为空,允许访问;blocked:不带http等协议头的资源允许访问
	#server_names:指定域名或IP;string:需要以~开头表示正则表达式。
	valid_referers none blocked www.baidu.com 192.168.200.222 *.example.com example.* www.example.org ~\.google\.; 
	if ($invalid_referer){ 
		return 403; 
	}
	root /usr/local/nginx/html; 
}

晋级方法:第三方模块【ngx_http_accesskey_module】

Rewrite功能配置O(∩_∩)O

主要的作用是用来实现URL的重写。Nginx使用的是ngx_http_rewrite_module模块来解析和处理Rewrite功能的相关配置。根据相关变量重定向和选择不同的配置,从一个 location 跳转到另一个 location,不过这样的循环最多可以执行10 次,超过后 nginx 将返回 500 错误。

重写与转发:重写浏览器地址会发生变化而地址转发则不变;一次重写产生2次请求,转发产生1次请求;抽重写到的页面必须是一个完整的路径而转发则不需要;重写是两次请求所以request范围内属性不能传递给新页面而转发可以;转发速度快于重写。

规则

set指令:【set $variable value】变量名要用 $ 开头,且不能与预设全局变量同名( _见附)。
if指令 :【if (condition){…}】根据选择不同的配置。 注意:尽量考虑使用 trp_files 代替。

  • if ($param)变量名对应的值为空或者是0是false,其他为true。
  • if ( $request_method = POST)注意post可与不加引号。
  • if ( $http_user_agent ~ MSIE)使用正则表达式对变量进行匹配(区分大小写,~ *是不区分),匹配成功返回true,否则返回false。变量与正则表达式之间使用"~ “,”~ * “,”!~ “,”!~*"来连接。 $ http_user_agent的值中是否包含MSIE字符串,如果包含返回 true。
  • if (-f $request_filename)判断请求的文件是否存在使用"-f"和"!-f"。
  • 判断请求的目录是否存在使用"-d"和"!-d";判断请求的目录或者文件是否存在使用"-e"和"!-e";判断请求的文件是否可执行使用"-x"和"!-x"
  • 不支持 if 条件的逻辑与&& 逻辑或|| 运算 ,而且不支持 if 的嵌套语法,否则会报下面的错误:nginx: [emerg] invalid condition。(可以用变量的方式来间接实现)
    • 如: if ($arg_unitid = 42012 && $uri ~/thumb/){ echo “www.ttlsa.com”;},可以写成set $flag 0;if ($uri ~ ^/thumb/[0-9]+_160.jpg$){ set $flag “${flag}1” ;} if ($arg_unitid = 42012){set $flag “${flag}1”;} if ($flag = “011”){ echo “www.ttlsa.com”;}

break指令 :处于同一作用域的Nginx配置中,位于它前面的指令配置生效,位于后面的指令配置无效。
return指令 :该指令用于完成对请求的处理,直接向客户端返回响应状态代码。

rewrite指令:【rewrite regex replacement [flag];】该指令通过正则表达式的使用来改变URI。可以同时存在一个或者多个指令,按照顺序依次对URL进行匹配和处理。replacement:匹配成功后,用于替换URI中被截取内容的字符串。如果该字符串是以"http://"或者"https://"开头的,则不会继续向下对URI进行其他处理,而是直接返回重写后的URI给客户端。flag:用来设置rewrite对URI的处理行为 lastbreakredirectpermanent

rewrite_log指令:该指令配置是否开启URL重写日志的输出功能。默认off。开启后,URL重写的相关日志将以notice级别输出到error_log指令配置的日志文件汇总。

uninitialized_variable_warn : 控制是否记录未初始化变量的警告信息。默认开启ON

组成部分
  1. 任何重写规则的第一部分都是一个正则表达式。
    可以使用括号来捕获,后续可以根据位置来将其引用,位置变量值取决于捕获正则表达式中的顺序,$1 引用第一个括号中的值,$2 引用第二个括号中的值,以此类推。如:
    ^/images/([a-z]{2})/([a-z0-9]{5})/(.*).(png|jpg|gif)$
    • $1 是两个小写字母组成的字符串,$2 是由小写字母和 0 到 9 的数字组成的 5 个字符的字符串,$3 将是个文件名,
    • $4 是 png、jpg、gif 中的其中一个。
  2. 重写规则的第二部分是 URI
    请求被改写。该 URI 可能包含正则表达式中的捕获的位置参数或这个级别下的 nginx 任何配置变量。如:
    /data?file=$3.$4
    如果这个 URI 不匹配 nginx 配置的任何 location,那么将给客户端返回 301(永久重定向)或 302(临时重定向)的状态码来表示重定向类型。该状态码可以通过第三个参数来明确指定。
  3. 重写规则的第三部分
    第三部分也就是尾部的标记(flag)。 last 标记将导致重写后的 URI 搜索匹配 nginx 的其他 location,最多可循环 10 次。如:
    rewrite ‘^/images/([a-z]{2})/([a-z0-9]{5})/(.*).(png|jpg|gif)$’ /data?file=$3.$4 last;
    break 指令可以当做自身指令。如:
    if ($bwhog) {
    — limit_rate 300k;
    break;
    }
    另一个停止重写模块处理指令是 return, 来控制主 HTTP 模块处理请求。 这意味着,nginx 直接返回信息给客户端,与 error_page 结合为客户端呈现格式化的 HTML 页面或激活不同的模块来完成请求。如果状态码附带文字段落,该文本将被放置在响应主体。相反,如果状态码后面是一个 URL,该 URL 将成为 location 头补值。没有状态码的 URL 将被视为一个 302 状态码。如:
    location = /image404.html {
    — return 404 “image not found\n”;
    }
案例

域名跳转

server{ 
	listen 80; 
	server_name www.360buy.com www.jingdong.com; 
	#在域名跳转的过程中携带请求的URI $1
	rewrite ^(.*) http://www.jd.com$1 permanent; 
}
http {
	 # 定义 image 日志格式
 	log_format imagelog '[$time_local] ' $image_file ' ' $image_type ' ' $body_bytes_sent ' ' $status;
 	# 开启重写日志
 	rewrite_log on;
 	server {
 		root /home/www;
 		location / {
 			# 重写日志输出规则信息
 			error_log logs/rewrite.log notice; 
 			# 注意这里要用‘’单引号引起来,避免{}
 			rewrite '^/images/([a-z]{2})/([a-z0-9]{5})/(.*)\.(png|jpg|gif)$' /data?file=$3.$4;
 			# 注意不能在上面这条规则后面加上“last”参数,否则下面的 set 指令不会执行
 			set $image_file $3;
 			set $image_type $4;
 		}
 		location /data {
 			# 指定针对图片的日志格式,来分析图片类型和大小
 			access_log logs/images.log mian;
 			root /data/images;
 			# 应用前面定义的变量。判断首先文件在不在,不在再判断目录在不在,如果还不在就跳转到最后一个 url 里
 			try_files /$arg_file /image404.html;
 		}
 		location = /image404.html {
 			# 图片不存在返回特定的信息
 			return 404 "image not found\n";
 		}
	}
}
  • 实例1 要将home目录重定向到主页面上,目录结构:/index ;/home/index
   # 如果想分别记录各个部分的 URL,可以使用正则表达式来捕获 URI,然后,给变量分配指定位置变量
   # 指定$scheme 和$host 变量,因为要做一个永久重定向并希望 nginx 使用相同的参数来构造 URL。
   rewrite ^/(home(/index)?|index(\.php)?)/?$  $scheme://$host/ permanent;
  • 实例2 当重写规则导致内部重定向或指示客户端调用该规则本身被定义的 location 时,必须采取特殊的动作来避免重写循环。(last 标志;break 标志)
server {
 	rewrite ^(/images)/(.*)\.(png|jpg|gif)$ $1/$3/$2.$3 last;
 	location /images/ {
 		rewrite ^(/images)/(.*)\.(png|jpg|gif)$ $1/$3/$2.$3 break;
 	}
}
  • 实例3 作为重写规则的一部分,传递新的查询字符串参数是使用重写规则的目标之一
rewrite  ^/images/(.*)_(\d+)x(\d+)\.(png|jpg|gif)$   /resizer/$1.$4?width=$2&height=$3?  last;

nginx 重写规则说起来挺简单的,做起来就难,重点在于正则表达式,同时,还需要考虑到 nginx 执行顺序。

CDN 调度器 HAProxy、Nginx、Varnish

部署在用户先访问到的那几台服务器上,负责定位 IP 然后重定向用户请求的那个软件,我们叫它“调度器”。

将全网 IP 分为若干个 IP 段组,分组的依据通常是运营商或者地域,目的是让相同网络环境中的用户聚集到相同的组内;依据 CDN 服务器们的网络和容量,确定哪些 CDN 服务器适合服务哪些 IP 段组。

智能 DNS 是办法之一,稳定可靠且有效。缺点如下:

  1. 需要特别精细的调度时。由于大多数 DNS Server 不支持 DNS 扩展协议,所以拿不到用户的真实 IP,只能根据 Local DNS 来调度。
  2. 访问特别频繁时。由于每次调度都将触发一次 DNS,如果请求变得密集,DNS 请求本身带来的开销也会相应变 大;
  3. 需要根据服务器的带宽容量、连接数、负载情况、当机与否来调度时。由于 DNS Server 没有 CDN 节点服务器 的信息,这种调度会变得困难。

解决方案“调度器”:将用户先行引导到某一台或几台统一的服务器上去;让它拿到用户的真实 IP,计算出服务他的服务器;通过 HTTP302 或其它方式把用户定位到最终服务器上。

Nginx 可以在核心模块 HttpGeoModule(http://wiki.nginx.org/HttpGeoModule)的配合下实现调度:

http{ 
	...
	
	geo $useriprang {
		ranges;
		default a;
		0.0.0.1-0.8.255.255 a;
		0.9.0.0-0.255.255.255 a;
		1.0.0.0-1.0.0.255 a;
		1.0.1.0-1.0.1.255 b;
		1.0.2.0-1.0.3.255 b;
		1.0.4.0-1.0.7.255 a;
		...
		223.255.252.0-223.255.253.255 c;
		223.255.254.0-223.255.254.255 a;
		223.255.255.0-223.255.255.255 a;
	}
 
	upstream backend {
		server 127.0.0.1:81;
	}
 
	server {
		listen 80;
		client_max_body_size 10240m;

		location / {
			proxy_redirect off;
			proxy_pass http://backend$request_uri&useriprang=$useriprang;
			proxy_next_upstream http_502 http_504 error timeout invalid_header;
			proxy_cache cache_one;
			proxy_cache_key $host:$server_port$uri$is_args$args;
			expires 5s;
		}
	}
	...
}

域名镜像:部分资源跳转.
镜像网站指定是将一个完全相同的网站分别放置到几台服务器上,并分别使用独立的URL进行访问。其中一台服务器上的网站叫主站,其他的为镜像网站。镜像网站和主站没有太大的区别,可以把镜像网站理解为主站的一个备份节点。可以通过镜像网站提供网站在不同地区的响应速度。镜像网站可以平衡网站的流量负载、可以解决网络宽带限制、封锁等

server { 
	listen 80; 
	server_name rewrite.myweb.com; 
	location ^~ /source1{ 
		#proxy_pass http://zhu.myweb.com/web$1;
		rewrite ^/source1(.*)$ http://zhu.myweb.com/web$1 last; 	
	}
	location ^~ /source2{ 
		rewrite ^/source2(.*) http://zhu.myweb.com/web$1 last; 
	} 
} 

独立域名

server{ 
	listen 80; 
	server_name search.hm.com; 
	rewrite ^(.*) http://www.hm.com/search$1 ; 
}
server{ 
	listen 81; 
	server_name item.hm.com; 
	rewrite ^(.*) http://www.hm.com/item$1 ; 
}

目录自定添加”/“【0.8.48之后忽略,默认server_name_in_redirect为off】

server { 
	listen 80; 
	server_name localhost; 
	server_name_in_redirect on; 
	location /hm { 
		if (-d $request_filename){ 
			rewrite ^/(.*)([^/])$ http://$host/$1$2/ permanent;
		} 
	} 
}

合并目录
包含URL的目录层级一般不要超过三层,否则的话不利于搜索引擎的搜索也给客户端的
输入带来了负担,但是将所有的文件放在一个目录下又会导致文件资源管理混乱并且访问文件的速度也会随着文件增多而慢下来,这两个问题是相互矛盾的,那么使用rewrite来解决上述问题:http://www.web.name/server/11/22/33/44/20.html (5层)

#客户端只需要输入http://www.web.name/server-11-22-33-44-20.html就可以访问到20.html页面了。这里也充分利用了rewrite指令支持正则表达式的特性。
server { 
	listen 80; 
	server_name www.web.name; 
	location /server{ 
		rewrite ^/server-([0-9]+)-([0-9]+)-([0-9]+)- ([0-9]+)\.html$ /server/$1/$2/$3/$4/$5.html last; 
	} 
}

防盗链
通过rewrite可以将防盗链的功能进行完善下,当出现防盗链的情况。

	if ($invalid_referer){ 
		#return 403;  return 403 没有权限; return http://www.baidu.com;
		rewrite ^/ http://www.web.com/images/forbidden.png;
	}
	locatin ~* ^.+\.(gif|jpg|png|swf|flv|rar|zip)${  
		valid_referers none blocked server_names *.web.com; 
		if ($invalid_referer){ 
			rewrite ^/ http://www.web.com/images/forbidden.png; 
		} 
	}
	location /file/{ 
		root /server/file/; 
		valid_referers none blocked server_names *.web.com; 
		if ($invalid_referer){ 
			rewrite ^/ http://www.web.com/images/forbidden.png; 
		}  
	}

反向代理

概述

简而言之就是正向代理代理的对象是客户端,反向代理代理的是服务端。

正向代理
#服务端设置
http { 
	log_format main 'client send request=>clientIp=$remote_addr serverIp=>$host'; 
	server{ 
		listen 80; 
		server_name localhost; 
		access_log logs/access.log main; 
		location { 
			root html; 
			index index.html index.htm; 
		} 
	}  
}
#客户端访问服务端,日志
client send request=>clientIp=192.168.1.1 serverIp=>192.168.1.200
#代理服务器设置,代理IP192.168.1.100
server { 
	listen 82; 
	resolver 8.8.8.8; 
	resolver_timeout 30s;
	location /{ 
		proxy_pass http://$host$request_uri; 
	} 
	access_log /data/httplogs/proxy-$host-aceess.log;
}
  • resolver 指令:配置段: http, server, location。配置 DNS 服务器 IP 地址。可以指定多个,以轮询方式请求。nginx 会缓存解析的结果。默认情况下,缓存时间是名字解析响应中的 TTL 字段的值,可以通过 valid 参数更改。
  • resolver_timeout 指令:解析超时时间
#internet选项->连接->局域网设置->代理服务器(代理IP和port)
#客户端设置后访问服务端,日志
client send request=>clientIp=192.168.1.100 serverIp=>192.168.1.200
反向代理

Nginx反向代理模块的指令是由【nginx_http_proxy_module】模块进行解析。
proxy:该指令用来设置被代理服务器地址,可以是主机名称、IP地址加端口号形式。

#最好非根目录不要加/
server { 
	listen 80; 
	server_name localhost; 
	location /{ 
		#proxy_pass http://192.168.200.146; 
		proxy_pass http://192.168.200.146/; 
	} 
	location /server{ 
		#proxy_pass http://192.168.200.146; 
		proxy_pass http://192.168.200.146/; 
	}
}
#当客户端访问 http://localhost/server/index.html
#第二个proxy_pass就变成了http://localhost/index.html效果 就不一样了。

proxy_set_header:Nginx服务器接收到的客户端请求的请求头信息,然后将新的请求头发送给代理的服务器。proxy_set_header field value
proxy_redirect:用来重置头信息中的"Location"和"Refresh"的值。【proxy_redirect redirect replacement】:默认是default。可以off关闭。

#代理服务端192.168.1.100
server { 
	listen 8081; 
	server_name localhost; 
	location / { 
		proxy_pass http://192.168.1.200:8081/; 
		#200是目标服务器;100是要替换的值。
		#默认值 是用proxy_pass变量做为第一个;location块uri变量为第二个
		proxy_redirect http://192.168.1.200 http://192.168.1.100; 
	} 
}

实战

# 如果服务器1、服务器2的内容不一样,那我们可以根据用户请求来分发到不同的服务器
#代理服务器
server { 
	listen 8082; 
	server_name localhost; 
	location /server1 { 
		proxy_pass http://192.168.200.146:9001/; 
	} 
	location /server2 { 
		proxy_pass http://192.168.200.146:9002/; 
	} 
}
#服务端
#server1 
server { 
	listen 9001; 
	server_name localhost; 
	default_type text/html; 
	return 200 '

192.168.200.146:9001

'
} #server2 server { listen 9002; server_name localhost; default_type text/html; return 200 '

192.168.200.146:9002

'
}

安全控制

安全隔离

通过代理分开了客户端到应用程序服务器端的连接,实现了安全措施。在反向代理之前设置防火墙,仅留一个入口供代理服务器访问。

使用SSL对流量进行加密

HTTPS是一种通过计算机网络进行安全通信的传输协议。它经由HTTP进行通信,利用 SSL / TLS 建立全通信,加密数据包,确保数据的安全性。TLS和SSL在传输层和应用层对网络连接进行加密。

参考ngx_http_gzip模块安装
将原有/usr/local/nginx/sbin/nginx进行备份
拷贝nginx之前的配置信息
在nginx的安装源码进行配置指定对应模块 ./configure – with-http_ssl_module
通过make模板进行编译
将objs下面的nginx移动到/usr/local/nginx/sbin下
在源码目录下执行 make upgrade进行升级,这个可以实现不停机添 加新模块的功能

server { 
	listen 443 ssl; 
	server_name localhost; 
	ssl_certificate server.cert; 
	ssl_certificate_key server.key; 
	ssl_session_cache shared:SSL:1m; 
	ssl_session_timeout 5m; 
	ssl_ciphers HIGH:!aNULL:!MD5; 
	ssl_prefer_server_ciphers on; 
	location / { 
		root html; 
		index index.html index.htm; 
	}
}

ssl_certificate:为当前这个虚拟主机指定一个带有PEM格式证书的证书。
ssl_certificate_key:该指令用来指定PEM secret key文件的路径
ssl_session_cache:该指令用来配置用于SSL会话的缓存。ssl_sesion_cache off|none|[builtin[:size]][shared:name:size]

参数 说明
off 禁用会话缓存,客户端不得重复使用会话
none 禁止使用会话缓存,客户端可以重复使用,但是并没有在缓存中存储会话参数
builtin 内置OpenSSL缓存,仅在一个工作进程中使用
shared 所有工作进程之间共享缓存,缓存的相关信息用name和size来指定

ssl_session_timeout:开启SSL会话功能后,设置客户端能够反复使用储存在缓存中的会话参数时间。
ssl_ciphers:指出允许的密码,密码指定为OpenSSL支持的格式。
ssl_prefer_server_ciphers:该指令指定是否服务器密码优先客户端密码.
openssl生成证书:openssl version

mkdir /root/cert 
cd /root/cert 
openssl genrsa -des3 -out server.key 1024 
openssl req -new -key server.key -out server.csr 
cp server.key server.key.org 
openssl rsa -in server.key.org -out server.key 
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
反向代理系统调优

提高IO吞吐效率。

  • Buffer缓冲:解决不同设备之间数据传递速度不一致导致的性能低的问题,缓冲中数据一旦此操作完成后,就可以删除。
  • Cache缓存:主要是备份,将被代理服务器的数据缓存一份到代理服务器,这样的话,客户端再次获取相同数据的时候,就只需要从代理服务器上获取,效 率较高,缓存中的数据可以重复使用,只有满足特定条件才会删除。
proxy_buffering on; 
proxy_buffer_size 4 32k; 
proxy_busy_buffers_size 64k; 
proxy_temp_file_write_size 64k;

proxy_buffering :该指令用来开启或者关闭代理服务器的缓冲区。
proxy_buffers:该指令用来指定单个连接从代理服务器读取响应的缓冲区的个数和大小。
proxy_buffer_size:该指令用来设置从被代理服务器获取的第一部分响应数据的大小。保持与proxy_buffers中的size一致即可,当然也可以更小。
proxy_busy_buffers_size:该指令用来限制同时处于BUSY状态的缓冲总大小。
proxy_temp_path:当缓冲区存满后,仍未被Nginx服务器完全接受,响应数据就会被临时存放在磁盘文件上,该指令设置文件路径(注意path最多设置三层)
proxy_temp_file_write_size:该指令用来设置磁盘上缓冲文件的大小。

负载均衡

概述

原理以及处理流程

应用集群:将同一应用部署到多台机器上,组成处理集群,接收负载均衡设备分发的请求,进行处理并返回响应的数据。
负载均衡器:将用户访问的请求根据对应的负载均衡算法,分发到集群中的一台服务器进行处理。
1、解决服务器的高并发压力,提高应用程序的处理性能。
2、提供故障转移,实现高可用。
3、通过添加或减少服务器数量,增强网站的可扩展性。
4、在负载均衡器上进行过滤,可以提高系统的安全性

处理方式

DNS轮询方式

域名系统(服务)协议(DNS)是一种分布式网络目录服务,主要用于域 名与 IP 地址的相互转换。
大多域名注册商都支持对同一个主机名添加多条A记录(一个域名对应多个IP),这就是DNS轮询,DNS服务器将解析请求按照A记录的顺序,随机分配到不同的IP上,这样就能完成简单的负载均衡。DNS轮询的成本非常低,在一些不重要的服务器,被经常使用。
缺点:
1.可靠性低
假设一个域名DNS轮询多台服务器,如果其中的一台服务器发生故障,那么所有的访问该服务器的请求将不会有所回应,即使你将该服务器的IP从DNS中去掉,但是由于各大宽带接入商将众多的DNS存放在缓存中,以节省访问时间,导致DNS不会实时更新。所以DNS轮流上一定程度上解决了负载均衡问题,但是却存在可靠性不高的缺点。
2.负载均衡不均衡
DNS负载均衡采用的是简单的轮询负载算法,不能区分服务器的差异,不能反映服务器的当前运行状态,不能做到为性能好的服务器多分配请求,另外本地计算机也会缓存已经解析的域名到IP地址的映射,这也会导致使用该DNS服务器的用户在一定时间内访问的是同一台Web服务器,从而引发Web服务器减的负载不均衡。
负载不均衡则会导致某几台服务器负荷很低,而另外几台服务器负荷确很高,处理请求的速度慢,配置高的服务器分配到的请求少,而配置低的服务器分配到的请求多。

四(传输)/七层(应用)负载均衡

OSI(open systeminterconnection),叫开放式系统互联模型。
所谓四层负载均衡指的是OSI七层模型中的传输层,主要是基于IP+PORT的负载均衡

实现四层负载均衡的方式: 
硬件:F5 BIG-IP、Radware等 
软件:LVS、Nginx、Hayproxy等

所谓的七层负载均衡指的是在应用层,主要是基于虚拟的URL或主机IP的负载均衡

实现七层负载均衡的方式: 
软件:Nginx、Hayproxy等

四/七的区别:

  1. 四层负载均衡数据包是在底层就进行了分发,而七层负载均衡数据包则在 最顶端进行分发,所以四层负载均衡的效率比七层负载均衡的要高。
  2. 四层负载均衡不识别域名,而七层负载均衡识别域名。
七层负责均衡

Nginx实现用到proxy_pass代理模块配置。Nginx的负载均衡是在Nginx的反向代理基础上把用户的请求根据指定的算法分发到一组【upstream虚拟服务池】。
Nginx笔记大全_第2张图片

upstream指令:【upstream name {…}】该指令是用来定义一组服务器,它们可以是监听不同端口的服务器,并且也可以是同时监听TCP和Unix socket的服务器。服务器可以指定不同的权重,默认为1。
server指令:【server name [paramerters]】该指令用来指定后端服务器的名称和一些参数,可以使用域名、IP、端口或者unix socket

#服务器端
server { 
	listen 9001; 
	server_name localhost; 
	default_type text/html; 
	location /{ 
		return 200 '

192.168.200.146:9001

'
; } } server { listen 9002; server_name localhost; default_type text/html; location /{ return 200 '

192.168.200.146:9002

'
; } }
#代理服务器
upstream backend{ 
	server 192.168.200.146:9091; 
	server 192.168.200.146:9092; 
}
server { 
	listen 8083; 
	server_name localhost; 
	location /{ 
		proxy_pass http://backend; 
	} 
} 

#tcp代理
#1.安装代理插件
./configure --add-module=/path/to/nginx_tcp_proxy_module     make     make install

# 配置
http {
 	listen 80;
 	location /status {
 		check_status;
 	}
}
tcp {
	# 这会出现一个问题,就是 tcp 连接会掉线。原因在于当服务端关闭连接的时候,客户端不可能立刻发觉连接已经被关闭,需要等到当 Nginx 在执行 check 规则时认为服务端链接关闭,此时 nginx 会关闭与客户端的连接
	## --start
	timeout 1d;
	proxy_read_timeout 10d;
	proxy_send_timeout 10d;
 	proxy_connect_timeout 30
	## --end
 	upstream cluster_www_ttlsa_com {
		# simple round-robin
 		server 127.0.0.1:1234;
 		check interval=3000 rise=2 fall=5 timeout=1000;
		#check interval=3000 rise=2 fall=5 timeout=1000 type=ssl_hello;
		#check interval=3000 rise=2 fall=5 timeout=1000 type=http;
		#check_http_send "GET / HTTP/1.0\r\n\r\n";
		#check_http_expect_alive http_2xx http_3xx;
 	}
 	server {
 		listen 8888;
 		proxy_pass cluster_www_ttlsa_com;
 		## --start
 		so_keepalive on;
 		tcp_nodelay on;
		## --end
 	}
}

四层负载均衡

Nginx在1.9之后,增加了一个stream模块,用来实现四层协议的转发、代理、负载均衡等。stream模块的用法跟http的用法类似,允许我们配置一组TCP或者UDP等协议的监听,然后通过proxy_pass来转发我们的请求,通过upstream添加多个后端服务,实现负载均衡。
Nginx笔记大全_第3张图片

添加stream模块的支持
需要在编译的时候加上–with-stream

将原有/usr/local/nginx/sbin/nginx进行备份
拷贝nginx之前的配置信息
在nginx的安装源码进行配置指定对应模块 ./configure – with-stream
通过make模板进行编译
将objs下面的nginx移动到/usr/local/nginx/sbin下
在源码目录下执行 make upgrade进行升级,这个可以实现不停机添 加新模块的功能

stream指令:该指令提供在其中指定流服务器指令的配置文件上下文。和http指令同级。
upstream指令:该指令和http的upstream指令是类似的。

stream { 
	upstream redisbackend {  
		server 192.168.200.146:6379; 
		server 192.168.200.146:6378; 
	} 
	upstream tomcatbackend { 
		server 192.168.200.146:8080; 
	} 
	server { 
		listen 81; 
		proxy_pass redisbackend; 
	} 
	server { 
		listen 82;
		proxy_pass tomcatbackend; 
	} 
} 

状态

down:将该服务器标记为永久不可用,那么该代理服务器将不参与负载均衡。
backup:将该服务器标记为备份服务器,当主服务器不可用时,将用来传递请求.
max_conns:用来设置代理服务器同时活动链接的最大数量,默认为0,表示不限制,使用该配置可以根据后端服务器处理请求的并发量来进行设置,防止后端服务器被压垮。
max_fails:设置允许请求代理服务器失败的次数,默认为1。
fail_timeout:设置经过max_fails失败后,服务暂停的时间,默认是10秒。

upstream backend{ 
	server 192.168.200.146:9001 down; 
	server 192.168.200.146:9002 backup;
	server 192.168.200.146:9003 max_fails=3 fail_timeout=15; 
}

策略

Nginx的upstream支持如下六种方式的分配算法,分别是:
轮询:是upstream模块负载均衡默认的策略。每个请求会按时间顺序逐个分配到不同的后端服务器。轮询不需要额外的配置。
weight加权:用来设置服务器的权重,默认为1,权重数据越大,被分配到请求的几率越大。

upstream backend{ 
	server 192.168.200.146:9001 weight=10; 
	server 192.168.200.146:9002 weight=5; 
}

ip_hash:ip_hash指令能够将某个客户端IP的请求通过哈希算法定位到同一台后端服务器上。这样,当来自某一个IP的用户在后端Web服务器A上登录后,在访问该站点的其他URL,能保证其访问的还是后端web服务器A。

#设置后端服务器权重等方法将不起作用
upstream backend{ 
	ip_hash;
	#least_conn;
	#hash &request_uri;
	#fair;
	server 192.168.200.146:9001; 
	server 192.168.200.146:9002; 
}

least_conn:最少连接,把请求转发给连接数较少的后端服务器。轮询算法是把请求平均的转发给各个后端,使它们的负载大致相同;但是,有些请求占用的时间很长,会导致其所在的后端负载较高。这种情况下,least_conn这种方式就可以达到更好的负载均衡效果。
url_hash: 按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,要配合缓存命中来使用。同一个资源多次请求,可能会到达不同的服务器上,导致不必要的多次下载,缓存命中率不高,以及一些资源时间的浪费。而使用url_hash,可以使得同一个url(也就是同一个资源请求)会到达同一台服务器,一旦缓存住了资源,再此收到请求,就可以从缓存中读取。
fair:fair采用的不是内建负载均衡使用的轮换的均衡算法,而是可以根据页面大小、加载时间长短智能的进行负载均衡。。需要添加[nginx-upstream-fair]

  1. 下载地址为: https://github.com/gnosek/nginx-upstream-fair
  2. unzip nginx-upstream-fair-master.zip
  3. mv nginx-upstream-fair-master fair
  4. ./configure --add-module=/root/fair
  5. make
    如果报错,在Nginx的源码中 src/http/ngx_http_upstream.h,找到
    ngx_http_upstream_srv_conf_s,在模块中添加添加default_port属性:
    in_port_t default_port
  6. 更新nginx 参考上面nginx更新步骤

案例

对特定资源实现负载均衡

服务器

upstream videobackend{ 
	server 192.168.200.146:9001; 
	server 192.168.200.146:9002; 
}
upstream filebackend{ 
	server 192.168.200.146:9003; 
	server 192.168.200.146:9004; 
}
server { 
	listen 8084; 
	server_name localhost; 
	location /video/ { 
		proxy_pass http://videobackend; 
	}
	location /file/ { 
		proxy_pass http://filebackend; 
	} 
}
实现带有URL重写的负载均衡
upstream backend{ 
	server 192.168.200.146:9001; 
	server 192.168.200.146:9002; 
}
server { 
	listen 80; 
	server_name localhost; 
	location /file/ { 
		rewrite ^(/file/.*) /server/$1 last; 
	}
	location / { 
		proxy_pass http://backend; 
	} 
}

缓存集成

概念

场景 作用
操作系统磁盘缓存 减少磁盘机械操作
数据库缓存 减少文件系统的IO操作
应用程序缓存 减少对数据库的查询
web服务器缓存(nginx) 减少对应用服务器请求次数
浏览器缓存 减少与后台的交互次数

优点:
1.减少数据传输,节省网络流量,加快响应速度,提升用户体验;
2.减轻服务器压力;
3.提供服务端的高可用性;
缓存的缺点
1.数据的不一致
2.增加成本

Nginx的web缓存服务

Nginx是基于Proxy Store来实现的,其原理是把URL及相关组合当做Key,在使用MD5算法对Key进行哈希,得到硬盘上对应的哈希目录路径,从而将缓存内容保存在该目录
中。它可以支持任意URL连接,同时也支持404/301/302这样的非200状态码。Nginx即可以支持对指定URL或者状态码设置过期时间,也可以使用purge命令来手动清除指定URL的缓存。
Nginx笔记大全_第4张图片

缓存设置相关指令

Nginx的web缓存服务主要是使用ngx_http_proxy_module模块相关指令集来完成

proxy_cache_path

该指定用于设置缓存文件的存放路径。proxy_cache_path path [levels=number] keys_zone=zone_name:zone_size [inactive=time][max_size=size];
path:缓存路径地址,如:/usr/local/proxy_cache
levels:缓存空间对应的目录,最多设置3层,每层取值为1|2

levels=1:2 缓存空间有两层目录,第一次是1个字母,第二次是2个 字母
举例说明:
itheima[key]通过MD5加密以后的值为 43c8233266edce38c2c9af0694e2107d
levels=1:2 最终的存储路径为/usr/local/proxy_cache/d/07
levels=2:1:2 最终的存储路径 为/usr/local/proxy_cache/7d/0/21
levels=2:2:2 最终的存储路径 为/usr/local/proxy_cache/7d/10/e2
注解:md5码队尾截取长度为2或长度为1。如:7d 10 e2

keys_zone:用来为这个缓存区设置名称和指定大小

keys_zone=itcast:200m 缓存区的名称是itcast,大小为200M,1M 大概能存储8000个keys

inactive:指定缓存的数据多次时间未被访问就将被删除。
max_size:设置最大缓存空间,如果缓存空间存满,默认会覆盖缓存时间最长的资源

http{
	proxy_cache_path /usr/local/proxy_cache keys_zone=itcast:200m levels=2:2:2 inactive=1d max_size=20g; 
}
proxy_cache

该指令用来开启或关闭代理缓存,如果是开启则自定使用哪个缓存区来进行缓存。
proxy_cache zone_name|off;

proxy_cache_key

该指令用来设置web缓存的key值,Nginx会根据key值MD5哈希存缓存

默认值:proxy_cache_key $scheme$proxy_host$request_uri;
proxy_cache_valid

该指令用来对不同返回状态码的URL设置不同的缓存时间

#为200和302的响应URL设置10分钟缓存
proxy_cache_valid 200 302 10m; 
#为404的响应URL设置1分钟缓存
proxy_cache_valid 404 1m; 
#对所有响应状态码的URL都设置1分钟缓存
proxy_cache_valid any 1m; 
proxy_cache_min_uses

该指令用来设置资源被访问多少次后被缓存。默认值1

proxy_cache_methods

该指令用户设置缓存哪些HTTP方法。默认值GET HEAD

缓存设置案例

JS文件缓存
#完成反向代理配置
http{ 
	upstream backend{ 
		server 192.168.200.146:8080; 
	} 
	server { 
		listen 8080; 
		server_name localhost; 
		location / { 
			proxy_pass http://backend/js/; 
		} 
	} 
}
#缓存配置
http{
	proxy_cache_path /usr/local/proxy_cache levels=2:1 keys_zone=itcast:200m inactive=1d max_size=20g; 
	upstream backend{ 
		server 192.168.200.146:8080; 
	}
	server { 
		listen 8080; 
		server_name localhost; 
		location / { 
			proxy_cache itcast; 
			proxy_cache_key itheima; 
			proxy_cache_min_uses 5; 
			proxy_cache_valid 200 5d; 
			proxy_cache_valid 404 30s; 
			proxy_cache_valid any 1m; 
			add_header nginx-cache "$upstream_cache_status"; 
			proxy_pass http://backend/js/; 
		} 
	} 
}

缓存清除

rm删除目录

rm -rf /usr/local/proxy_cache/…

第三方扩展模块ngx_cache_purge
ngx_cache_purge-2.3.tar.gz
tar -zxf ngx_cache_purge-2.3.tar.gz
mv ngx_cache_purge-2.3 purge
# 进入Nginx安装目录
./configure --add-module=/root/nginx/module/purge
make
mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginxold
cp objs/nginx /usr/local/nginx/sbin
make upgrade

##  联网安装
yum -y install zlib-devel pcre-devel openssl-devel # 安装依赖
tar –xvf ngx_cache_purge-1.4.tar.gz
tar –xvf nginx-1.0.11.tar.gz
cd nginx-1.0.11/
./configure – prefix=/usr/local/nginx – add-module=../ngx_cache_purge-1.4 – withhttp_stub_status_module – with-http_ssl_module – with-http_flv_module – withhttp_gzip_static_module
Make && make install
# 在nginx配置文件中进行如下配置
server{ 
	location ~/purge(/.*) { 
		proxy_cache_purge itcast itheima; 
	} 
}

设置资源不缓存

对于一些经常发生变化的数据,对于这些资源我们在缓存的过程中就需要进行过滤,不进行缓存。

proxy_no_cache

该指令是用来定义不将数据进行缓存的条件:proxy_no_cache string … ;
proxy_no_cache $cookie_nocache $arg_nocache $arg_comment;

proxy_cache_bypass

该指令是用来设置不从缓存中获取数据的条件:proxy_cache_bypass string …;
proxy_cache_bypass $cookie_nocache $arg_nocache $arg_comment;

$cookie_nocache 指的是当前请求的cookie中键的名称为nocache对应的值
$ arg_nocache和$arg_comment 指的是当前请求的参数中属性名为nocache和comment对应的属性值

server{ 
	listen 8080; 
	server_name localhost; 
	location / { 
		if ($request_uri ~ /.*\.js$){  
			#设置变量
			set $nocache 1; 
		} 
		#至少有一个不为空且不等于"0",则条件满足成立
		proxy_no_cache $nocache $cookie_nocache $arg_nocache $arg_comment; 
		proxy_cache_bypass $nocache $cookie_nocache $arg_nocache $arg_comment; 
	}  
}

服务器端集群搭建

(1)在Centos上准备一个Tomcat

1.Tomcat官网地址:https://tomcat.apache.org/
2.下载tomcat,本次课程使用的是apache-tomcat-8.5.59.tar.gz
3.将tomcat进行解压缩
mkdir web_tomcat
tar -zxf apache-tomcat-8.5.59.tar.gz -C /web_tomcat
4.启动tomcat
./bin/startup.sh
http://192.168.200.146:8080/demo/getAddress

upstream webservice { 
	server 192.168.200.146:8080; 
}
server{ 
	listen 80; 
	server_name localhost; 
	location /demo { 
		proxy_pass http://webservice; 
	} 
}

Nginx实现动静分离

静态资源交给Nginx来部署,非静态内容则交给Tomcat的服务器。
优点:

  • 前面我们介绍过Nginx在处理静态资源的时候,效率是非常高的,而且 Nginx的并发访问量也是名列前茅,而Tomcat则相对比较弱一些,所以 把静态资源交个Nginx后,可以减轻Tomcat服务器的访问压力并提高静 态资源的访问速度。
  • 动静分离以后,降低了动态资源和静态资源的耦合度。如动态资源宕机 了也不影响静态资源的展示。
upstream webservice { 
	server 192.168.200.146:8080; 
}
server{ 
	listen 80; 
	server_name localhost; 
	#动态资源
	location /demo { 
		proxy_pass http://webservice; 
	} 
	#静态资源
	location ~/.*\.(png|jpg|gif|js){ 
		root html/web; 
		gzip on; 
	}
	location ~ .*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|txt|js|css){  
    	root   /soft/nginx/static_resources;  
    	expires 7d;  
	}
	location / { 
		root html/web; 
		index index.html index.htm; 
	}
}
#访问http://192.168.200.133/index.html

实现集群

upstream webservice { 
	server 192.168.200.146:8080; 
	server 192.168.200.146:8180;
}

高可用解决方案

两台以上Nginx服务器对外提供服务。

Keepalived

使用Keepalived来解决,Keepalived 软件由 C 编写的,最初是专为 LVS负载均衡软件设计的,Keepalived 软件主要是通过 VRRP 协议实现高可用功能。
VRRP 协议将两台或多台路由器设备虚拟成一个设备,对外提供虚拟路由器IP,而在路由器组内部,如果实际拥有这个对外IP的路由器如果工作正常的话就是ASTER,MASTER实现针对虚拟路由器IP的各种网络功能。其他设备不拥有该虚拟IP,状态为BACKUP,处了接收MASTER的VRRP状态通告信息以外,不执行对外的网络功能。当主机失效时,BACKUP将接管原先MASTER的网络功能。
1.选择协议

VRRP可以把一个虚拟路由器的责任动态分配到局域网上的 VRRP 路由器 中的一台。其中的虚拟路由即Virtual路由是由VRRP路由群组创建的一个 不真实存在的路由,这个虚拟路由也是有对应的IP地址。而且VRRP路由1 和VRRP路由2之间会有竞争选择,通过选择会产生一个Master路由和一个 Backup路由。

2.路由容错协议

Master路由和Backup路由之间会有一个心跳检测,Master会定时告知 Backup自己的状态,如果在指定的时间内,Backup没有接收到这个通知 内容,Backup就会替代Master成为新的Master。Master路由有一个特 权就是虚拟路由和后端服务器都是通过Master进行数据传递交互的,而备 份节点则会直接丢弃这些请求和数据,不做处理,只是去监听Master的状 态

Nginx笔记大全_第5张图片

环境搭建
VIP IP 主机名 主/从
192.168.1.133 keepalived1
192.168.1.222
192.168.1.122 keepalived2
步骤1:从官方网站下载keepalived,官网地址 https://keepalived.org/ 
步骤2:将下载的资源上传到服务器 keepalived-2.0.20.tar.gz 
步骤3:创建keepalived目录,方便管理资源 
mkdir keepalived 
步骤4:将压缩文件进行解压缩,解压缩到指定的目录 
tar -zxf keepalived-2.0.20.tar.gz -C keepalived/ 
步骤5:对keepalived进行配置,编译和安装 
cd keepalived/keepalived-2.0.20 
./configure --sysconf=/etc --prefix=/usr/local 
make && make install

## 例如:
wget http://www.keepalived.org/software/keepalived-1.1.19.tar.gz
tar zxvf keepalived-1.1.19.tar.gz
cd keepalived-1.1.19
./configure –prefix=/usr/local/keepalived
make
make install
cp /usr/local/keepalived/sbin/keepalived /usr/sbin/
cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
cp /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/
mkdir /etc/keepalived

/etc/keepalived/keepalived.conf (keepalived的系统配置文件,我们主要操作的就是该文件),
/usr/local/sbin目录下的keepalived ,是系统配置脚本,用来启动和关闭keepalived

Keepalived配置文件介绍

这里面会分三部,第一部分是global全局配置、第二部分是vrrp相关配置、第三部分是LVS相关配置。

#global全局部分: 
global_defs {
	#通知邮件,当keepalived发送切换时需要发email给具体的邮箱 地址 
	notification_email { 
		leo_pic@163.com
		leorainbow@163.com 
	} 
	#设置发件人的邮箱信息 
	notification_email_from zhaomin@itcast.cn 
	#指定smpt服务地址 
	smtp_server 192.168.200.1 
	#指定smpt服务连接超时时间 
	smtp_connect_timeout 30 
	#运行keepalived服务器的一个标识,可以用作发送邮件的主题信息 
	router_id LVS_DEVEL 
	#默认是不跳过检查。检查收到的VRRP通告中的所有地址可能会比较 耗时,设置此命令的意思是,如果通告与接收的上一个通告来自相同的 master路由器,则不执行检查(跳过检查) 
	vrrp_skip_check_adv_addr 
	#严格遵守VRRP协议。 
	vrrp_strict 
	#在一个接口发送的两个免费ARP之间的延迟。可以精确到毫秒级。 默认是0 
	vrrp_garp_interval 0 
	#在一个网卡上每组na消息之间的延迟时间,默认为0 
	vrrp_gna_interval 0 
}

VRRP部分,该部分可以包含以下四个子模块 1. vrrp_script 2. vrrp_sync_group
3. garp_group 4. vrrp_instance。会用到1,4

#设置keepalived实例的相关信息,VI_1为VRRP实例名称 
vrrp_instance VI_1 { 
	state MASTER #有两个值可选MASTER主 BACKUP备 
	interface eth0 #vrrp实例绑定的接口,用于发送VRRP 包[当前服务器使用的网卡名称] 
	virtual_router_id 51#指定VRRP实例ID,范围是0-255 
	priority 100 #指定优先级,优先级高的将成为 MASTER 
	advert_int 1 #指定发送VRRP通告的间隔,单位是秒 
	authentication { 	#vrrp之间通信的认证信息 
		auth_type PASS #指定认证方式。PASS简单密码认证(推 荐) 
		auth_pass 1111 #指定认证使用的密码,最多8位 
	} 
	virtual_ipaddress { #虚拟IP地址设置虚拟IP地址,供用户 访问使用,可设置多个,一行一个 
		192.168.10.104/24
	} 
}

virtual_server 192.168.10.104 80 {
	delay_loop 6
	lb_algo rr
	lb_kind NAT
	nat_mask 255.255.255.0
	persistence_timeout 50
	protocol TCP
	real_server 192.168.10.251 80 {
		weight 3
		TCP_CHECK {
			connect_timeout 10
			nb_get_retry 3
			delay_before_retry 3
			connect_port 80
		}
	}
	real_server 192.168.200.148 80 {
		weight 3
		TCP_CHECK {
			connect_timeout 10
			nb_get_retry 3
			delay_before_retry 3
			connect_port 80
		}
	}
}

配置备用调度器的 keepalived,只需要将 state MASTER 改为 state BACKUP,降低 priority 100 的值:
state MASTER —> state BACKUP
priority 100 —> priority 99 (此值必须低于主的)
主备启动
/etc/init.d/keepalived start

服务器1配置

global_defs { 
	notification_email { 
		tom@itcast.cn 
		jerry@itcast.cn 
	}
	notification_email_from zhaomin@itcast.cn 
	smtp_server 192.168.200.1 
	smtp_connect_timeout 30 
	router_id keepalived1 
	vrrp_skip_check_adv_addr 
	vrrp_strict 
	vrrp_garp_interval 0 
	vrrp_gna_interval 0 
}  
vrrp_instance VI_1 { 
	state MASTER 
	interface ens33 
	virtual_router_id 51 
	priority 100 
	advert_int 1 
	authentication { 
		auth_type PASS 
		auth_pass 1111 
	} 
	virtual_ipaddress { 
		192.168.200.222 
	} 
}

服务器2配置

! Configuration File for keepalived
global_defs { 
	notification_email { 
		tom@itcast.cn 
		jerry@itcast.cn 
	}
	notification_email_from zhaomin@itcast.cn 
	smtp_server 192.168.200.1 
	smtp_connect_timeout 30 
	router_id keepalived2 
	vrrp_skip_check_adv_addr 
	vrrp_strict 
	vrrp_garp_interval 0 
	vrrp_gna_interval 0 
}  
vrrp_instance VI_1 { 
	state BACKUP
	interface ens33 
	virtual_router_id 51 
	priority 100 
	advert_int 1 
	authentication { 
		auth_type PASS 
		auth_pass 1111 
	} 
	virtual_ipaddress { 
		192.168.200.222 
	} 
}
访问测试
  1. 启动keepalived之前,咱们先使用命令 ip a ,查看192.168.200.133
    和192.168.200.122这两台服务器的IP情况
  2. 分别启动两台服务器的keepalived,再次通过 ip a查看ip 主133多了 222 IP
cd /usr/local/sbin 
./keepalived
  1. 当把192.168.200.133服务器上的keepalived关闭后,再次查看ip,222不见了。从机器122 多了222 IP
  2. 启动133里keepalived,133会变成master。

通过上述的测试,我们会发现,虚拟IP(VIP)会在MASTER节点上,当MASTER节点上的keepalived出问题以后,因为BACKUP无法收到MASTER发出的VRRP状态通过信息,就会直接升为MASTER。VIP也 会"漂移"到新的MASTER

keepalived之vrrp_script

keepalived只能做到对网络故障和keepalived本身的监控,即当出现网络故障或者keepalived本身出现问题时,进行切换。但是这些还不够,我们还需要监控keepalived所在服务器上的其他业务,比如Nginx,如果Nginx出现异常了,仅仅keepalived保持正常,是无法完成系统的正常工作的,因此需要根据业务进程的运行状态决定是否需要进行主备切换,这个时候,我们可以通过编写脚本对业务进程进行检测监控

  1. 在keepalived配置文件中添加对应的配置像
vrrp_script 脚本名称 { 
	script "脚本位置" 
	interval 3 #执行时间间隔 
	weight -20 #动态调整vrrp_instance的优先级 
} 
  1. 编写脚本 ck_nginx.sh,然后chmod 755 ck_nginx.sh
#!/bin/bash 
num=`ps -C nginx --no-header | wc -l` 
if [ $num -eq 0 ];then 
	/usr/local/nginx/sbin/nginx 
	sleep 2 
	if [ `ps -C nginx --no-header | wc -l` -eq 0 ]; then 
		killall keepalived 
	fi 
fi
# -C(command):指定命令的所有进程。 --no-header:排除标题
  1. 将脚本添加到
vrrp_script ck_nginx { 
	script "/etc/keepalived/ck_nginx.sh" #执行脚本的位置 
	interval 2 #执行脚本的周期,秒为单位 
	weight -20 #权重的计算方式 
} 
vrrp_instance VI_1 { 
	state MASTER 
	interface ens33 
	virtual_router_id 10 
	priority 100 
	advert_int 1
	authentication { 
		auth_type PASS 
		auth_pass 1111 
	} 
	virtual_ipaddress { 
		192.168.200.111 
	} 
	track_script { 
		ck_nginx 
	} 
}
  1. 如果效果没有出来,可以使用 tail -f /var/log/messages查看日志信息,找对应的错误信息。

通常如果master服务死掉后backup会变成master,但是当master服务又好了的时候 master此时会抢占VIP,这样就会发生两次切换对业务繁忙的网站来说是不好的。所以我们要在配置文件加入 nopreempt 非抢占,但是这个参数只能用于state 为backup,故我们在用HA的时候最好master 和backup的state都设置成backup 让其通过priority来竞争.

Nginx制作下载站点

location /download{ 
	root /usr/local; 
	#启用或禁用目录列表输出 默认off
	autoindex on; 
	#对应HTLM格式,指定是否在目录列表展示文件的详细大小,最好off。on是按bytes
	autoindex_exact_size on; 
	#设置目录列表的格式html|xml|json|jsonp
	autoindex_format html; 
	#对应HTML格式,是否在目录列表上显示时间,默认off
	autoindex_localtime on; 
}

用户认证模块

认证需要做的就是根据用户输入的用户名和密码来判定用户是否为合法用户,如果是则放行访问,如果不是则拒绝访问。
Nginx对应用户认证这块是通过【ngx_http_auth_basic_module】模块来实现的

相关指令

auth_basic:使用“ HTTP基本认证”协议启用用户名和密码的验证。开启后,服务端会返回401,指定的字符串会返回到客户端,给用户以提示信息。
auth_basic_user_file:指定用户名和密码所在文件,该文件中的用户名和密码的设置,密码需要进行加密。

location /download{ 
	root /usr/local; 
	autoindex on; 
	autoindex_exact_size on; 
	autoindex_format html; 
	autoindex_localtime on; 
	auth_basic 'please input your auth'; 
	auth_basic_user_file htpasswd; 
}

我们需要使用htpasswd工具生成

yum install -y httpd-tools
htpasswd -c /usr/local/nginx/conf/htpasswd username // 创建一个新文件记录用户名和密码 
htpasswd -b /usr/local/nginx/conf/htpasswd username password //在指定文件新增一个用户名和密码 
htpasswd -D /usr/local/nginx/conf/htpasswd username // 从指定文件删除一个用户信息 
htpasswd -v /usr/local/nginx/conf/htpasswd username // 验证用户名和密码是否正确

上述方式虽然能实现用户名和密码的验证,但是大家也看到了,所有的用户名和密码信息都记录在文件里面,如果用户量过大的话,这种方式就显得有点麻烦了,这时候我们就得**通过后台业务代码来进行用户权限的校验**了。

Nginx的扩展模块

Lua

Lua是一种轻量、小巧的脚本语言,用标准C语言编写并以源代码形式开发。设计的目的是为了嵌入到其他应用程序中,从而为应用程序提供灵活的扩展和定制功能。
Lua有其自身的特点:
(1)轻量级:用标准C语言编写并以源代码形式开发,编译后仅仅一百余千字节,可 以很方便的嵌入到其他程序中。
(2)可扩展:提供非常丰富易于使用的扩展接口和机制,由宿主语言(通常是C或 C++)提供功能,Lua可以使用它们,就像内置的功能一样。
(3)支持面向过程编程和函数式编程。
游戏开发、独立应用脚本、web应用脚本、扩展和数据库插件、系统安全等应用场景。
服务器

#Lua的官网地址为: https://www.lua.org
wget https://www.lua.org/ftp/lua-5.4.1.tar.gz
cd lua-5.4.1  
# 如果test失败: yum install -y readline-devel
make linux test 
make install
lua -v
进入Lua

Lua有两种交互方式,分别是:交互式和脚本式。
交互式:lua -i ; print(“hello world”);
脚本式:是将代码保存到一个以lua为扩展名的文件中并执行的方式。

#方式一 类似java源文件形式
#hello.lua文件内容
print("Hello World")
-----
#命令执行文件
lua hello.lua
#方式二 类似脚本文件形式
#hello.lua文件内容。
#第一句指定lua解释器所在位置。一般情况下#!就是用来指定用哪个程序来运行本文件。
#!/usr/local/bin/lua
print("Hello World!!!")
-----
#命令执行文件
chmod 755 hello.lua
./hello.lua

补充一点,如果想在交互式中运行脚本式的hello.lua中的内容,我们可以使用一个dofile函数,如:dofile(“lua_demo/hello.lua”)

Lua的注释

单行注释:–注释内容。
多行注释:- -[[ 注释内容 --]] 。取消多行前面再加-就可以。- - -

标识符(变量名)

这块建议大家最好不要使用下划线加大写字母的标识符,因为Lua的保留字也是这样定义的,容易发生冲突。注意Lua是区分大小写字母的。

关键字

需要注意的:local、repeat、until、nil。其他类似if、for等

运算符

Lua中支持的运算符有算术运算符、关系运算符、逻辑运算符、其他运算符。
算术运算符:+、-、*、/、%、^乘幂
关系运算符:==、~=、>、<、>=、<=
逻辑运算符:and &&、 or || 、 not !
其他运算符:. .连接两个字符串 ;# 一元预算法,返回字符串或表的长度(#“rain” -->4)。

全局变量&局部变量

在Lua语言中,全局变量无须声明即可使用。在默认情况下,变量总是认为是全局的,如果未提前赋值,默认为nil。要想声明一个局部变量,需要使用local来声明。

8个数据类型
nil(空,无效值)

nil是一种只有一个nil值的类型,它的作用可以用来与其他所有值进行区分,也可以当想要移除一个变量时,只需要将该变量名赋值为nil,垃圾回收就会会释放该变量所占用的内存。

boolean(布尔,true/false)

在Lua语言中,只会将false和nil视为假,其他的都视为真,特别是在条件检测中0和空字符串都会认为是真,这个和我们熟悉的大多数语言不太一样。

number(数值)

在Lua5.3版本开始,Lua语言为数值格式提供了两种选择:integer(整型) 和float(双精度浮点型)。
不管是整型还是双精度浮点型,使用type()函数来取其类型,都会返回的是number,所以它们之间是可以相互转换的,同时,具有相同算术值的整型值和浮点型值在Lua语言中是相等的。

string(字符串)

Lua语言中的字符串即可以表示单个字符,也可以表示一整本书籍。在Lua语言中,操作100K或者1M个字母组成的字符串的程序很常见。
可以使用单引号或双引号来声明字符串。如果声明的字符串比较长或者有多行,则可以使用如下方式进行声明:

#短字符串
a = "hello"
b = 'world'
a .. b  -->hello world
#长字符串
html = [[ 
	 
		 Lua-string<<span class="token operator">/</span>title> <<span class="token operator">/</span>head> 
		<body> <a href=<span class="token string">"http://www.lua.org"</span>>Lua<<span class="token operator">/</span>a> <<span class="token operator">/</span>body> 
	<<span class="token operator">/</span>html> 
<span class="token punctuation">]</span><span class="token punctuation">]</span>
</code></pre> 
  <h6>function(函数)</h6> 
  <p>在 Lua语言中,函数( Function )是对语句和表达式进行抽象的主要方式。</p> 
  <pre><code class="prism language-powershell"><span class="token comment">#定义函数的语法为:</span>
<span class="token keyword">function</span> functionName<span class="token punctuation">(</span>params<span class="token punctuation">)</span> 
<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
<span class="token keyword">end</span>
<span class="token comment">#例子</span>
<span class="token keyword">function</span> f<span class="token punctuation">(</span>a<span class="token punctuation">,</span>b<span class="token punctuation">)</span> 
	print<span class="token punctuation">(</span>a<span class="token punctuation">,</span>b<span class="token punctuation">)</span> 
<span class="token keyword">end</span> 
f<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">--</span>> nil nil 
f<span class="token punctuation">(</span>2<span class="token punctuation">)</span> <span class="token operator">--</span>> 2 nil 
f<span class="token punctuation">(</span>2<span class="token punctuation">,</span>6<span class="token punctuation">)</span> <span class="token operator">--</span>> 2 6 
f<span class="token punctuation">(</span>2<span class="token punctuation">.</span>6<span class="token punctuation">.</span>8<span class="token punctuation">)</span> <span class="token operator">--</span>> 2 6 <span class="token punctuation">(</span>8被丢弃<span class="token punctuation">)</span>
</code></pre> 
  <pre><code class="prism language-powershell"><span class="token comment">#可变长参数函数</span>
<span class="token keyword">function</span> add<span class="token punctuation">(</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span> 
	a<span class="token punctuation">,</span>b<span class="token punctuation">,</span>c=<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> 
	print<span class="token punctuation">(</span>a<span class="token punctuation">)</span> 
	print<span class="token punctuation">(</span>b<span class="token punctuation">)</span> 
	print<span class="token punctuation">(</span>c<span class="token punctuation">)</span> 
<span class="token keyword">end</span> 
add<span class="token punctuation">(</span>1<span class="token punctuation">,</span>2<span class="token punctuation">,</span>3<span class="token punctuation">)</span> <span class="token operator">--</span>> 1 2 3
</code></pre> 
  <pre><code class="prism language-powershell"><span class="token comment">#函数返回值可以有多个</span>
<span class="token keyword">function</span> f<span class="token punctuation">(</span>a<span class="token punctuation">,</span>b<span class="token punctuation">)</span> 
 	<span class="token keyword">return</span> a<span class="token punctuation">,</span>b 
<span class="token keyword">end</span> 
x<span class="token punctuation">,</span>y=f<span class="token punctuation">(</span>11<span class="token punctuation">,</span>22<span class="token punctuation">)</span> <span class="token operator">--</span>> x=11<span class="token punctuation">,</span>y=22
</code></pre> 
  <h6>table(表)</h6> 
  <p>table是Lua语言中最主要和强大的数据结构。使用表, Lua 语言可以以一种简单、统一且高效的方式表示数组、集合、记录和其他很多数据结构。 Lua语言中的表本质上是一种辅助数组。这种数组比Java中的数组更加灵活,可以使用数值做索引,也可以使用字符串或其他任意类型的值作索引(除nil外)。</p> 
  <pre><code class="prism language-powershell"><span class="token comment">#arr[0]值nil;arr[1]值TOM;数组默认从1开始</span>
arr = <span class="token punctuation">{</span><span class="token string">"TOM"</span><span class="token punctuation">,</span><span class="token string">"JERRY"</span><span class="token punctuation">,</span><span class="token string">"ROSE"</span><span class="token punctuation">}</span>
<span class="token comment">#下面与上面效果一样</span>
arr =<span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> arr<span class="token punctuation">[</span>1<span class="token punctuation">]</span>=<span class="token string">"TOM"</span>
<span class="token comment">#用字符串表示索引</span>
arr = <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> arr<span class="token punctuation">[</span><span class="token string">"X"</span><span class="token punctuation">]</span>=10 <span class="token punctuation">;</span> arr<span class="token punctuation">[</span><span class="token string">"Y"</span><span class="token punctuation">]</span>=20
<span class="token comment">#取值</span>
print<span class="token punctuation">(</span>arr<span class="token punctuation">[</span><span class="token string">"X"</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> print<span class="token punctuation">(</span>arr<span class="token punctuation">.</span>Y<span class="token punctuation">)</span>
<span class="token comment">#混合</span>
arr = <span class="token punctuation">{</span><span class="token string">"TOM"</span><span class="token punctuation">,</span>X=10<span class="token punctuation">,</span><span class="token string">"JERRY"</span><span class="token punctuation">,</span>Y=20<span class="token punctuation">,</span><span class="token string">"ROSE"</span><span class="token punctuation">,</span>Z=30<span class="token punctuation">}</span><span class="token comment">#弱类型</span>
TOM:arr<span class="token punctuation">[</span>1<span class="token punctuation">]</span> <span class="token punctuation">;</span> 10:arr<span class="token punctuation">[</span><span class="token string">"X"</span><span class="token punctuation">]</span> <span class="token punctuation">;</span> JERRY:arr<span class="token punctuation">[</span>2<span class="token punctuation">]</span> <span class="token punctuation">;</span> 20:arr<span class="token punctuation">.</span>Y
</code></pre> 
  <h6>thread(线程)</h6> 
  <p>在Lua中,thread用来表示执行的独立线路,用来执行协同程序。</p> 
  <h6>userdata(用户数据)</h6> 
  <p>userdata是一种用户自定义数据,用于表示一种由应用程序或C/C++语言库所创建的类型。</p> 
  <h5>控制结构</h5> 
  <p>用于循环的 while、 repeat 和 for。 所有的控制结构语法上都有一个显式的终结符: end 用于终结 if、 for 及 while 结构, until 用于终结repeat 结构。</p> 
  <h6>if then elseif else</h6> 
  <pre><code class="prism language-powershell"> <span class="token keyword">function</span> show<span class="token punctuation">(</span>age<span class="token punctuation">)</span> 
 	<span class="token keyword">if</span> age<=18 then 
 		<span class="token keyword">return</span> <span class="token string">"青少年"</span> 
 	<span class="token keyword">elseif</span> age>18 and age<=45 then 
 		<span class="token keyword">return</span> <span class="token string">"青年"</span> 
 	<span class="token keyword">elseif</span> age>45 and age<=60 then 
 		<span class="token keyword">return</span> <span class="token string">"中年人"</span> 
 	<span class="token keyword">elseif</span> age>60 then 
 		<span class="token keyword">return</span> <span class="token string">"老年人"</span> 
 	<span class="token keyword">end</span>
 <span class="token keyword">end</span>
</code></pre> 
  <h6>while循环</h6> 
  <pre><code class="prism language-powershell"><span class="token keyword">function</span> testWhile<span class="token punctuation">(</span><span class="token punctuation">)</span> 
	local i = 1 
	<span class="token keyword">while</span> i<=10 <span class="token keyword">do</span> 
		print<span class="token punctuation">(</span>i<span class="token punctuation">)</span> 
		i=i+1 
	<span class="token keyword">end</span> 
<span class="token keyword">end</span>
</code></pre> 
  <h6>repeat循环</h6> 
  <p>repeat-until语句会重复执行其循环体直到条件为真时结束(<code>while循环相反</code>)。 由于条件测试在循环体之后执行,所以循环体至少会执行一次。</p> 
  <pre><code class="prism language-powershell"><span class="token keyword">function</span> testRepeat<span class="token punctuation">(</span><span class="token punctuation">)</span> 
	local i = 10 
	repeat 
		print<span class="token punctuation">(</span>i<span class="token punctuation">)</span> i=i-1 
	<span class="token keyword">until</span> i < 1 
<span class="token keyword">end</span> 
</code></pre> 
  <h6>for循环</h6> 
  <pre><code class="prism language-powershell"><span class="token comment">#10是步长,for(int i=1;i+10;i<100)</span>
<span class="token keyword">for</span> i = 1<span class="token punctuation">,</span>100<span class="token punctuation">,</span>10 <span class="token keyword">do</span> 
	print<span class="token punctuation">(</span>i<span class="token punctuation">)</span> 
<span class="token keyword">end</span>
<span class="token comment">#类似foreach</span>
arr = <span class="token punctuation">{</span><span class="token string">"TOME"</span><span class="token punctuation">,</span><span class="token string">"JERRY"</span><span class="token punctuation">,</span><span class="token string">"ROWS"</span><span class="token punctuation">,</span><span class="token string">"LUCY"</span><span class="token punctuation">}</span> 
<span class="token keyword">for</span> i<span class="token punctuation">,</span>v in ipairs<span class="token punctuation">(</span>arr<span class="token punctuation">)</span> <span class="token keyword">do</span> 
	print<span class="token punctuation">(</span>i<span class="token punctuation">,</span>v<span class="token punctuation">)</span> 
<span class="token keyword">end</span>
<span class="token comment">#ipairs 与pairs 区别,前面是整数索引,不会显示x坐标值;后面pairs会显示</span>
arr = <span class="token punctuation">{</span><span class="token string">"TOME"</span><span class="token punctuation">,</span><span class="token string">"JERRY"</span><span class="token punctuation">,</span><span class="token string">"ROWS"</span><span class="token punctuation">,</span>x=<span class="token string">"JACK"</span><span class="token punctuation">,</span><span class="token string">"LUCY"</span><span class="token punctuation">}</span>
<span class="token keyword">for</span> i<span class="token punctuation">,</span>v in pairs<span class="token punctuation">(</span>arr<span class="token punctuation">)</span> <span class="token keyword">do</span> 
	print<span class="token punctuation">(</span>i<span class="token punctuation">,</span>v<span class="token punctuation">)</span>  <span class="token comment">#1 TOM 2 JERRY 3 ROWS 4 LUCY x JACK</span>
<span class="token keyword">end</span>
</code></pre> 
  <h4>ngx_lua模块</h4> 
  <p>淘宝开发的ngx_lua模块通过将lua解释器集成进Nginx,可以采用lua脚本实现业务逻辑,由于lua的紧凑、快速以及内建协程,所以在保证高并发服务能力的同时极大地降低了业务逻辑实现成本。</p> 
  <h5>环境准备</h5> 
  <h6>方式一:lua-nginx-module</h6> 
  <p>(1)LuaJIT是采用C语言编写的Lua代表的解释器.<br> 官网上对应的下载地址:http://luajit.org/download/LuaJIT-2.0.5.tar.gz</p> 
  <pre><code class="prism language-powershell">wget http:<span class="token operator">/</span><span class="token operator">/</span>luajit<span class="token punctuation">.</span>org/download/LuaJIT-2<span class="token punctuation">.</span>0<span class="token punctuation">.</span>5<span class="token punctuation">.</span>tar<span class="token punctuation">.</span>gz
tar <span class="token operator">-</span>zxf LuaJIT-2<span class="token punctuation">.</span>0<span class="token punctuation">.</span>5<span class="token punctuation">.</span>tar<span class="token punctuation">.</span>gz
cd LuaJIT-2<span class="token punctuation">.</span>0<span class="token punctuation">.</span>5
make && make install
</code></pre> 
  <p>(2)下载lua-nginx-module</p> 
  <pre><code class="prism language-powershell">wget https:<span class="token operator">/</span><span class="token operator">/</span>github<span class="token punctuation">.</span>com/openresty/lua-nginx-module/archive/v0<span class="token punctuation">.</span>10<span class="token punctuation">.</span>16rc4<span class="token punctuation">.</span>tar<span class="token punctuation">.</span>gz
tar <span class="token operator">-</span>zxf lua-nginx-module-0<span class="token punctuation">.</span>10<span class="token punctuation">.</span>16rc4<span class="token punctuation">.</span>tar<span class="token punctuation">.</span>gz
<span class="token function">mv</span> lua-nginx-module-0<span class="token punctuation">.</span>10<span class="token punctuation">.</span>16rc4 lua-nginx-module

</code></pre> 
  <pre><code class="prism language-powershell"><span class="token comment">#导入环境变量,告诉Nginx去哪里找luajit</span>
export LUAJIT_LIB=<span class="token operator">/</span>usr/local/lib 
export LUAJIT_INC=<span class="token operator">/</span>usr/local/include/luajit-2<span class="token punctuation">.</span>0
</code></pre> 
  <pre><code class="prism language-powershell"><span class="token comment">#进入Nginx的目录执行如下命令:</span>
<span class="token punctuation">.</span><span class="token operator">/</span>configure <span class="token operator">--</span>prefix=<span class="token operator">/</span>usr/local/nginx <span class="token operator">--</span>add- module=<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token operator">/</span>lua-nginx-module 
make && make install

<span class="token comment">#如果启动提示libluajit-5.1.so.2错误。设置软链接。</span>
ln <span class="token operator">-</span>s <span class="token operator">/</span>usr/local/lib/libluajit-5<span class="token punctuation">.</span>1<span class="token punctuation">.</span>so<span class="token punctuation">.</span>2 <span class="token operator">/</span>lib64/libluajit-5<span class="token punctuation">.</span>1<span class="token punctuation">.</span>so<span class="token punctuation">.</span>2
<span class="token comment">#如果提示resty.core没有找到。一种安装,另一种禁用restry模块。</span>
http<span class="token punctuation">{</span>
	lua_load_resty_core off<span class="token punctuation">;</span> 
<span class="token punctuation">}</span>

<span class="token comment">#安装成功测试</span>
location <span class="token operator">/</span>lua<span class="token punctuation">{</span> 
	default_type <span class="token string">'text/html'</span><span class="token punctuation">;</span> 
	content_by_lua <span class="token string">'ngx.say("<h1>HELLO,LUA</h1>")'</span><span class="token punctuation">;</span> 
<span class="token punctuation">}</span>
</code></pre> 
  <h6>方式二:OpenRestry</h6> 
  <p>OpenResty是由淘宝工程师开发的,其官方网站(http://openresty.org/)。OpenResty内部就已经集成了Nginx和Lua,所以我们使用起来会更加方便。</p> 
  <pre><code class="prism language-powershell"><span class="token comment">#安装</span>
wget https:<span class="token operator">/</span><span class="token operator">/</span>openresty<span class="token punctuation">.</span>org/download/openresty- 1<span class="token punctuation">.</span>15<span class="token punctuation">.</span>8<span class="token punctuation">.</span>2<span class="token punctuation">.</span>tar<span class="token punctuation">.</span>gz
tar <span class="token operator">-</span>zxf openresty-1<span class="token punctuation">.</span>15<span class="token punctuation">.</span>8<span class="token punctuation">.</span>2<span class="token punctuation">.</span>tar<span class="token punctuation">.</span>gz
cd openresty-1<span class="token punctuation">.</span>15<span class="token punctuation">.</span>8<span class="token punctuation">.</span>2
<span class="token punctuation">.</span><span class="token operator">/</span>configure
make && make install
cd <span class="token operator">/</span>usr/local/openresty/nginx/
vim nginx<span class="token punctuation">.</span>conf
location <span class="token operator">/</span>lua<span class="token punctuation">{</span> default_type <span class="token string">'text/html'</span><span class="token punctuation">;</span> content_by_lua <span class="token string">'ngx.say(" <h1>HELLO,OpenRestry</h1>")'</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
在sbin目录下启动nginx

</code></pre> 
  <h5>使用</h5> 
  <p>xxx_by_lua ,指令后面跟的是 lua指令;xxx_by_lua_file 指令后面跟的是 lua文件。</p> 
  <h6>init_by_lua*</h6> 
  <p>该指令在每次Nginx重新加载配置时执行,可以用来完成一些耗时模块的 加载,或者初始化一些全局配置。</p> 
  <h6>init_worker_by_lua*</h6> 
  <p>该指令用于启动一些定时任务,如心跳检查、定时拉取服务器配置等。</p> 
  <h6>set_by_lua*</h6> 
  <p>该指令只要用来做变量赋值,这个指令一次只能返回一个值,并将结果赋 值给Nginx中指定的变量。</p> 
  <h6>rewrite_by_lua*</h6> 
  <p>该指令用于执行内部URL重写或者外部重定向,典型的如伪静态化URL重 写,本阶段在rewrite处理阶段的最后默认执行。</p> 
  <h6>access_by_lua*</h6> 
  <p>该指令用于访问控制。例如,如果只允许内网IP访问。</p> 
  <h6>content_by_lua*</h6> 
  <p>该指令是应用最多的指令,大部分任务是在这个阶段完成的,其他的过程 往往为这个阶段准备数据,正式处理基本都在本阶段</p> 
  <h6>header_filter_by_lua*</h6> 
  <p>该指令用于设置应答消息的头部信息。</p> 
  <h6>body_filter_by_lua*</h6> 
  <p>该指令是对响应数据进行过滤,如截断、替换。</p> 
  <h6>log_by_lua*</h6> 
  <p>该指令用于在log请求处理阶段,用Lua代码处理日志,但并不替换原有 log处理。</p> 
  <h6>balancer_by_lua*</h6> 
  <p>该指令主要的作用是用来实现上游服务器的负载均衡器算法</p> 
  <h6>ssl_certificate_by_*</h6> 
  <p>该指令作用在Nginx和下游服务开始一个SSL握手操作时将允许本配置项 的Lua代码。</p> 
  <pre><code class="prism language-powershell">http:<span class="token operator">/</span><span class="token operator">/</span>192<span class="token punctuation">.</span>168<span class="token punctuation">.</span>200<span class="token punctuation">.</span>133?name=张三&gender=1 
Nginx接收到请求后,根据gender传入的值,如果gender传入的是1, 则在页面上展示 
张三先生<span class="token punctuation">,</span>如果gender传入的是0,则在页面上展示张三女士<span class="token punctuation">,</span>如果未传或 者传入的不是1和2则在页面上展示张三。
<span class="token comment">## 实现代码</span>
location <span class="token operator">/</span>getByGender <span class="token punctuation">{</span> 
	default_type <span class="token string">'text/html'</span><span class="token punctuation">;</span> 
	set_by_lua <span class="token variable">$name</span> <span class="token string">" 
		local uri_args = ngx.req.get_uri_args() 
		gender = uri_args['gender'] 
		name = uri_args['name'] 
		if gender=='1' then 
			return name..'先生' 
		elseif gender=='0' then 
			return name..'女士' 
		else 
			return name 
		end 
	"</span><span class="token punctuation">;</span> 
	header_filter_by_lua <span class="token string">" 
		ngx.header.aaa='bbb' 
	"</span><span class="token punctuation">;</span> 
	<span class="token keyword">return</span> 200 <span class="token variable">$name</span><span class="token punctuation">;</span> 
<span class="token punctuation">}</span>
</code></pre> 
  <h5>操作Redis</h5> 
  <p>Nginx支 持3种方法访问Redis,分别是HttpRedis模块、HttpRedis2Module、lua-resty-redis库。</p> 
  <h6>lua-resty-redis</h6> 
  <p>准备一个redis环境,然后准备对应的API;</p> 
  <blockquote> 
   <p>lua-resty-redis提供了访问Redis的详细API,包括创建对接、连 接、操作、数据处理等。这些API基本上与Redis的操作一一对应。<br> (1)redis = require “resty.redis”<br> (2)new 语法: redis,err = redis:new(),创建一个Redis对象。<br> (3)connect 语 法:ok,err=redis:connect(host,port[,options_table]),设 置连接Redis的连接信息。 ok:连接成功返回 1,连接失败返回nil err:返回对应的错误信息<br> (4)set_timeout 语法: redis:set_timeout(time) ,设置请求操作Redis的超 时时间。<br> (5)close 语法: ok,err = redis:close(),关闭当前连接,成功返回1, 失败返回nil和错误信息<br> (6)redis命令对应的方法 在lua-resty-redis中,所有的Redis命令都有自己的方法,方 法名字和命令名字相同,只是全部为小写。</p> 
  </blockquote> 
  <p>效果实现</p> 
  <pre><code class="prism language-powershell">location <span class="token operator">/</span> <span class="token punctuation">{</span> 
	default_type <span class="token string">"text/html"</span><span class="token punctuation">;</span> 
	content_by_lua_block<span class="token punctuation">{</span> 
		local redis = require <span class="token string">"resty.redis"</span> <span class="token operator">--</span> 引入 Redis 
		local redisObj = redis:new<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">--</span>创建Redis对象 
		redisObj:set_timeout<span class="token punctuation">(</span>1000<span class="token punctuation">)</span> <span class="token operator">--</span>设置超时数据为1s 
		local ok<span class="token punctuation">,</span>err = redisObj:connect<span class="token punctuation">(</span><span class="token string">"192.168.200.1"</span><span class="token punctuation">,</span>6379<span class="token punctuation">)</span> <span class="token operator">--</span>设置redis连接 信息 
		<span class="token keyword">if</span> not ok then <span class="token operator">--</span>判断是否连接成功 
			ngx<span class="token punctuation">.</span>say<span class="token punctuation">(</span><span class="token string">"failed to connection redis"</span><span class="token punctuation">,</span>err<span class="token punctuation">)</span> 
			<span class="token keyword">return</span> 
		<span class="token keyword">end</span> 
		ok<span class="token punctuation">,</span>err = redisObj:<span class="token function">set</span><span class="token punctuation">(</span><span class="token string">"username"</span><span class="token punctuation">,</span><span class="token string">"TOM"</span><span class="token punctuation">)</span><span class="token operator">--</span>存入 数据 
		<span class="token keyword">if</span> not ok then <span class="token operator">--</span>判断是否存入成功 
			ngx<span class="token punctuation">.</span>say<span class="token punctuation">(</span><span class="token string">"failed to set username"</span><span class="token punctuation">,</span>err<span class="token punctuation">)</span> 
			<span class="token keyword">return</span> 
		<span class="token keyword">end</span> 
		local res<span class="token punctuation">,</span>err = redisObj:get<span class="token punctuation">(</span><span class="token string">"username"</span><span class="token punctuation">)</span> <span class="token operator">--</span>从 redis中获取数据 
		ngx<span class="token punctuation">.</span>say<span class="token punctuation">(</span>res<span class="token punctuation">)</span> <span class="token operator">--</span>将数据写会消息体中 
		redisObj:close<span class="token punctuation">(</span><span class="token punctuation">)</span> 
	<span class="token punctuation">}</span> 
<span class="token punctuation">}</span>
</code></pre> 
  <h5>操作Mysql</h5> 
  <p>MySQL是一个使用广泛的关系型数据库。在ngx_lua中,MySQL有两种访问模式,分别是使<br> (1)用ngx_lua模块和lua-resty-mysql模块:这两个模块是安装OpenResty时默认安装的。<br> (2)使用drizzle_nginx_module(HttpDrizzleModule)模块:需要单独安装,这个库现不在OpenResty中。</p> 
  <h6>lua-resty-mysql</h6> 
  <p>lua-resty-mysql是OpenResty开发的模块,使用灵活、功能强大,适合复杂的业务场景,同时支持存储过程的访问。<br> 准备一个mysql环境,然后准备对应的API;</p> 
  <blockquote> 
   <p>(1)引入"resty.mysql"模块 local mysql = require “resty.mysql”<br> (2)new 创建一个MySQL连接对象,遇到错误时,db为nil,err为错误描 述信息语法: db,err = mysql:new()<br> (3)connect 尝试连接到一个MySQL服务器语法:ok,err=db:connect(options),options是一个参数的 Lua表结构,里面包含数据库连接的相关信息 host:服务器主机名或IP地址 port:服务器监听端口,默认为3306 user:登录的用户名 password:登录密码 database:使用的数据库名<br> (4)set_timeout 设置子请求的超时时间(ms),包括connect方法 语法:db:set_timeout(time)<br> (5)close 关闭当前MySQL连接并返回状态。如果成功,则返回1;如果出现任 何错误,则将返回nil和错误描述。 语法:db:close()<br> (6)send_query 异步向远程MySQL发送一个查询。如果成功则返回成功发送的字节 数;如果错误,则返回nil和错误描述 语法:bytes,err=db:send_query(sql)<br> (7)read_result 从MySQL服务器返回结果中读取一行数据。res返回一个描述OK包 或结果集包的Lua表,语法:<br> res, err, errcode, sqlstate = db:read_result()<br> res, err, errcode, sqlstate = db:read_result(rows) :rows指定返回结果集的最大值,默认为4 如果是查询,则返回一个容纳多行的数组。每行是一个数据列的 key-value对,如<br> { {id=1,username=“TOM”,birthday=“1988-11- 11”,salary=10000.0}, {id=2,username=“JERRY”,birthday=“1989-11- 11”,salary=20000.0} }<br> 如果是增删改,则返回类上如下数据<br> { insert_id = 0, server_status=2, warning_count=1, affected_rows=2, message=nil }<br> 返回值:<br> res:操作的结果集<br> err:错误信息<br> errcode:MySQL的错误码,比如1064<br> sqlstate:返回由5个字符组成的标准SQL错误码,比如 42000</p> 
  </blockquote> 
  <pre><code class="prism language-powershell">create database nginx_db<span class="token punctuation">;</span> 
use nginx_db<span class="token punctuation">;</span> 
create table users<span class="token punctuation">(</span> 
	id int primary key auto_increment<span class="token punctuation">,</span> 
	username varchar<span class="token punctuation">(</span>30<span class="token punctuation">)</span><span class="token punctuation">,</span> 
	birthday date<span class="token punctuation">,</span> 
	salary double 
<span class="token punctuation">)</span><span class="token punctuation">;</span> 
insert into users<span class="token punctuation">(</span>id<span class="token punctuation">,</span>username<span class="token punctuation">,</span>birthday<span class="token punctuation">,</span>salary<span class="token punctuation">)</span> values<span class="token punctuation">(</span>null<span class="token punctuation">,</span><span class="token string">"TOM"</span><span class="token punctuation">,</span><span class="token string">"1988-11-11"</span><span class="token punctuation">,</span>10000<span class="token punctuation">.</span>0<span class="token punctuation">)</span><span class="token punctuation">;</span> 
insert into users<span class="token punctuation">(</span>id<span class="token punctuation">,</span>username<span class="token punctuation">,</span>birthday<span class="token punctuation">,</span>salary<span class="token punctuation">)</span> values<span class="token punctuation">(</span>null<span class="token punctuation">,</span><span class="token string">"JERRY"</span><span class="token punctuation">,</span><span class="token string">"1989-11-11"</span><span class="token punctuation">,</span>20000<span class="token punctuation">.</span>0<span class="token punctuation">)</span><span class="token punctuation">;</span> 
insert into users<span class="token punctuation">(</span>id<span class="token punctuation">,</span>username<span class="token punctuation">,</span>birthday<span class="token punctuation">,</span>salary<span class="token punctuation">)</span> values<span class="token punctuation">(</span>null<span class="token punctuation">,</span><span class="token string">"ROWS"</span><span class="token punctuation">,</span><span class="token string">"1990-11-11"</span><span class="token punctuation">,</span>30000<span class="token punctuation">.</span>0<span class="token punctuation">)</span><span class="token punctuation">;</span> 
insert into users<span class="token punctuation">(</span>id<span class="token punctuation">,</span>username<span class="token punctuation">,</span>birthday<span class="token punctuation">,</span>salary<span class="token punctuation">)</span> values<span class="token punctuation">(</span>null<span class="token punctuation">,</span><span class="token string">"LUCY"</span><span class="token punctuation">,</span><span class="token string">"1991-11-11"</span><span class="token punctuation">,</span>40000<span class="token punctuation">.</span>0<span class="token punctuation">)</span><span class="token punctuation">;</span> 
insert into users<span class="token punctuation">(</span>id<span class="token punctuation">,</span>username<span class="token punctuation">,</span>birthday<span class="token punctuation">,</span>salary<span class="token punctuation">)</span> values<span class="token punctuation">(</span>null<span class="token punctuation">,</span><span class="token string">"JACK"</span><span class="token punctuation">,</span><span class="token string">"1992-11-11"</span><span class="token punctuation">,</span>50000<span class="token punctuation">.</span>0<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre> 
  <p>实现代码</p> 
  <pre><code class="prism language-powershell">location <span class="token operator">/</span><span class="token punctuation">{</span> 
	content_by_lua_block<span class="token punctuation">{</span> 
		local mysql = require <span class="token string">"resty.mysql"</span> 
		local db = mysql:new<span class="token punctuation">(</span><span class="token punctuation">)</span>  
		local ok<span class="token punctuation">,</span>err = db:connect<span class="token punctuation">{</span> 
			host=<span class="token string">"192.168.200.111"</span><span class="token punctuation">,</span> 
			port=3306<span class="token punctuation">,</span> 
			user=<span class="token string">"root"</span><span class="token punctuation">,</span> 
			password=<span class="token string">"123"</span><span class="token punctuation">,</span> 
			database=<span class="token string">"nginx_db"</span> 
		<span class="token punctuation">}</span> 
		db:set_timeout<span class="token punctuation">(</span>1000<span class="token punctuation">)</span> 
		db:send_query<span class="token punctuation">(</span><span class="token string">"select * from users where id =1"</span><span class="token punctuation">)</span> 
		local res<span class="token punctuation">,</span>err<span class="token punctuation">,</span>errcode<span class="token punctuation">,</span>sqlstate = db:read_result<span class="token punctuation">(</span><span class="token punctuation">)</span> 
		ngx<span class="token punctuation">.</span>say<span class="token punctuation">(</span>res<span class="token punctuation">[</span>1<span class="token punctuation">]</span><span class="token punctuation">.</span>id<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token string">","</span><span class="token punctuation">.</span><span class="token punctuation">.</span>res<span class="token punctuation">[</span>1<span class="token punctuation">]</span><span class="token punctuation">.</span>username<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token string">","</span><span class="token punctuation">.</span><span class="token punctuation">.</span>res<span class="token punctuation">[</span>1<span class="token punctuation">]</span><span class="token punctuation">.</span> birthday<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token string">","</span><span class="token punctuation">.</span><span class="token punctuation">.</span>res<span class="token punctuation">[</span>1<span class="token punctuation">]</span><span class="token punctuation">.</span>salary<span class="token punctuation">)</span> 
		db:close<span class="token punctuation">(</span><span class="token punctuation">)</span> 
	<span class="token punctuation">}</span> 
<span class="token punctuation">}</span>
</code></pre> 
  <h6>使用lua-cjson处理查询结果</h6> 
  <p>read_result()得到的结果res都是table类型,要想在页面上展示,就必须知道table的具体数据结构才能进行遍历获取。处理起来比较麻烦,接下来我们介绍一种简单方式cjson,使用它就可以将table类型的数据转换成json字符串,把json字符串展示在页面上即可。<br> 步骤一:引入cjson<br> 步骤二:调用cjson的encode方法进行类型转换<br> 步骤三:使用</p> 
  <pre><code class="prism language-powershell">location <span class="token operator">/</span><span class="token punctuation">{</span> 
	content_by_lua_block<span class="token punctuation">{</span> 
		local mysql = require <span class="token string">"resty.mysql"</span> 
		local cjson = require <span class="token string">"cjson"</span> 
		local db = mysql:new<span class="token punctuation">(</span><span class="token punctuation">)</span> 
		local ok<span class="token punctuation">,</span>err = db:connect<span class="token punctuation">{</span> 
			host=<span class="token string">"192.168.200.111"</span><span class="token punctuation">,</span> port=3306<span class="token punctuation">,</span> user=<span class="token string">"root"</span><span class="token punctuation">,</span> password=<span class="token string">"123456"</span><span class="token punctuation">,</span> database=<span class="token string">"nginx_db"</span> 
		<span class="token punctuation">}</span>
		db:set_timeout<span class="token punctuation">(</span>1000<span class="token punctuation">)</span> 
		<span class="token operator">--</span>db:send_query<span class="token punctuation">(</span><span class="token string">"select * from users where id = 2"</span><span class="token punctuation">)</span> 
		db:send_query<span class="token punctuation">(</span><span class="token string">"select * from users"</span><span class="token punctuation">)</span> 
		local res<span class="token punctuation">,</span>err<span class="token punctuation">,</span>errcode<span class="token punctuation">,</span>sqlstate = db:read_result<span class="token punctuation">(</span><span class="token punctuation">)</span> 
		ngx<span class="token punctuation">.</span>say<span class="token punctuation">(</span>cjson<span class="token punctuation">.</span>encode<span class="token punctuation">(</span>res<span class="token punctuation">)</span><span class="token punctuation">)</span> 
		<span class="token keyword">for</span> i<span class="token punctuation">,</span>v in ipairs<span class="token punctuation">(</span>res<span class="token punctuation">)</span> <span class="token keyword">do</span> 
			ngx<span class="token punctuation">.</span>say<span class="token punctuation">(</span>v<span class="token punctuation">.</span>id<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token string">","</span><span class="token punctuation">.</span><span class="token punctuation">.</span>v<span class="token punctuation">.</span>username<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token string">","</span><span class="token punctuation">.</span><span class="token punctuation">.</span>v<span class="token punctuation">.</span>birthday<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token string">","</span><span class="token punctuation">.</span><span class="token punctuation">.</span> v<span class="token punctuation">.</span>salary<span class="token punctuation">)</span>
		<span class="token keyword">end</span> 
		db:close<span class="token punctuation">(</span><span class="token punctuation">)</span> 
	<span class="token punctuation">}</span> 
<span class="token punctuation">}</span>
</code></pre> 
  <h6>lua-resty-mysql实现数据库的增删改</h6> 
  <p>优化send_query和read_result。<br> 本方法是send_query和read_result组合的快捷方法。<br> res, err, errcode, sqlstate = db:query(sql[,rows])</p> 
  <pre><code class="prism language-powershell">location <span class="token operator">/</span><span class="token punctuation">{</span> 
	content_by_lua_block<span class="token punctuation">{</span> 
		local mysql = require <span class="token string">"resty.mysql"</span> 
		local db = mysql:new<span class="token punctuation">(</span><span class="token punctuation">)</span> 
		local ok<span class="token punctuation">,</span>err = db:connect<span class="token punctuation">{</span> 
			host=<span class="token string">"192.168.200.1"</span><span class="token punctuation">,</span> 
			port=3306<span class="token punctuation">,</span> 
			user=<span class="token string">"root"</span><span class="token punctuation">,</span> 
			password=<span class="token string">"123456"</span><span class="token punctuation">,</span> 
			database=<span class="token string">"nginx_db"</span><span class="token punctuation">,</span> 
			max_packet_size=1024<span class="token punctuation">,</span>  
			compact_arrays=false 
		<span class="token punctuation">}</span> 
		db:set_timeout<span class="token punctuation">(</span>1000<span class="token punctuation">)</span> 
		local res<span class="token punctuation">,</span>err<span class="token punctuation">,</span>errcode<span class="token punctuation">,</span>sqlstate = db:query<span class="token punctuation">(</span><span class="token string">"select * from users"</span><span class="token punctuation">)</span> 
		<span class="token operator">--</span>local res<span class="token punctuation">,</span>err<span class="token punctuation">,</span>errcode<span class="token punctuation">,</span>sqlstate = db:query<span class="token punctuation">(</span><span class="token string">"insert into users(id,username,birthday,salary) values(null,'zhangsan','2020-11-11',32222.0)"</span><span class="token punctuation">)</span> 
		<span class="token operator">--</span>local res<span class="token punctuation">,</span>err<span class="token punctuation">,</span>errcode<span class="token punctuation">,</span>sqlstate = db:query<span class="token punctuation">(</span><span class="token string">"update users set username='lisi' where id = 6"</span><span class="token punctuation">)</span> 
		<span class="token operator">--</span>local res<span class="token punctuation">,</span>err<span class="token punctuation">,</span>errcode<span class="token punctuation">,</span>sqlstate = db:query<span class="token punctuation">(</span><span class="token string">"delete from users where id = 6"</span><span class="token punctuation">)</span> db:close<span class="token punctuation">(</span><span class="token punctuation">)</span> 
	<span class="token punctuation">}</span> 
<span class="token punctuation">}</span>
</code></pre> 
  <h5>综合小案例</h5> 
  <p>使用ngx_lua模块完成Redis缓存预热。<br> 分析:<br> (1)先得有一张表(users)<br> (2)浏览器输入如下地址</p> 
  <blockquote> 
   <p>http://191.168.200.133?username=TOM</p> 
  </blockquote> 
  <p>(3)从表中查询出符合条件的记录,此时获取的结果为table类型<br> (4)使用cjson将table数据转换成json字符串<br> (5)将查询的结果数据存入Redis中</p> 
  <pre><code class="prism language-powershell">init_by_lua_block<span class="token punctuation">{</span> 
	redis = require <span class="token string">"resty.redis"</span> 
	mysql = require <span class="token string">"resty.mysql"</span> 
	cjson = require <span class="token string">"cjson"</span> 
<span class="token punctuation">}</span> 
location <span class="token operator">/</span><span class="token punctuation">{</span> 
	default_type <span class="token string">"text/html"</span><span class="token punctuation">;</span> 
	content_by_lua_block<span class="token punctuation">{</span> 
	<span class="token operator">--</span>获取请求的参数username 
	local <span class="token keyword">param</span> = ngx<span class="token punctuation">.</span>req<span class="token punctuation">.</span>get_uri_args<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">[</span><span class="token string">"username"</span><span class="token punctuation">]</span> 
	<span class="token operator">--</span>建立mysql数据库的连接 
	local db = mysql:new<span class="token punctuation">(</span><span class="token punctuation">)</span> 
	local ok<span class="token punctuation">,</span>err = db:connect<span class="token punctuation">{</span> 
		host=<span class="token string">"192.168.200.111"</span><span class="token punctuation">,</span> port=3306<span class="token punctuation">,</span> user=<span class="token string">"root"</span><span class="token punctuation">,</span>  password=<span class="token string">"123456"</span><span class="token punctuation">,</span> database=<span class="token string">"nginx_db"</span> 
	<span class="token punctuation">}</span> 
	<span class="token keyword">if</span> not ok then 
		ngx<span class="token punctuation">.</span>say<span class="token punctuation">(</span><span class="token string">"failed connect to mysql:"</span><span class="token punctuation">,</span>err<span class="token punctuation">)</span> 
		<span class="token keyword">return</span> 
	<span class="token keyword">end</span> 
	<span class="token operator">--</span>设置连接超时时间 
	db:set_timeout<span class="token punctuation">(</span>1000<span class="token punctuation">)</span> 
	<span class="token operator">--</span>查询数据 
	local sql = <span class="token string">""</span><span class="token punctuation">;</span> 
	<span class="token keyword">if</span> not <span class="token keyword">param</span> then
		sql=<span class="token string">"select * from users"</span> 
	<span class="token keyword">else</span> 
		sql=<span class="token string">"select * from users where username="</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token string">"'"</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token keyword">param</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token string">"'"</span> 
	<span class="token keyword">end</span> 
	local res<span class="token punctuation">,</span>err<span class="token punctuation">,</span>errcode<span class="token punctuation">,</span>sqlstate=db:query<span class="token punctuation">(</span>sql<span class="token punctuation">)</span> 
	<span class="token keyword">if</span> not res then 
		ngx<span class="token punctuation">.</span>say<span class="token punctuation">(</span><span class="token string">"failed to query from mysql:"</span><span class="token punctuation">,</span>err<span class="token punctuation">)</span> 
		<span class="token keyword">return</span> 
	<span class="token keyword">end</span> 
	<span class="token operator">--</span>连接redis 
	local <span class="token function">rd</span> = redis:new<span class="token punctuation">(</span><span class="token punctuation">)</span> 
	ok<span class="token punctuation">,</span>err = <span class="token function">rd</span>:connect<span class="token punctuation">(</span><span class="token string">"192.168.200.111"</span><span class="token punctuation">,</span>6379<span class="token punctuation">)</span> 
	<span class="token keyword">if</span> not ok then 
		ngx<span class="token punctuation">.</span>say<span class="token punctuation">(</span><span class="token string">"failed to connect to redis:"</span><span class="token punctuation">,</span>err<span class="token punctuation">)</span> 
		<span class="token keyword">return</span> 
	<span class="token keyword">end</span> 
	<span class="token function">rd</span>:set_timeout<span class="token punctuation">(</span>1000<span class="token punctuation">)</span> 
	<span class="token operator">--</span>循环遍历数据 
	<span class="token keyword">for</span> i<span class="token punctuation">,</span>v in ipairs<span class="token punctuation">(</span>res<span class="token punctuation">)</span> <span class="token keyword">do</span> 
		<span class="token function">rd</span>:<span class="token function">set</span><span class="token punctuation">(</span><span class="token string">"user_"</span><span class="token punctuation">.</span><span class="token punctuation">.</span>v<span class="token punctuation">.</span>username<span class="token punctuation">,</span>cjson<span class="token punctuation">.</span>encode<span class="token punctuation">(</span>v<span class="token punctuation">)</span><span class="token punctuation">)</span> 
	<span class="token keyword">end</span> 
	ngx<span class="token punctuation">.</span>say<span class="token punctuation">(</span><span class="token string">"success"</span><span class="token punctuation">)</span> 
	<span class="token function">rd</span>:close<span class="token punctuation">(</span><span class="token punctuation">)</span> 
	db:close<span class="token punctuation">(</span><span class="token punctuation">)</span> 
	<span class="token punctuation">}</span> 
<span class="token punctuation">}</span>
</code></pre> 
  <hr> 
  <h3>附录A 编译参数详解</h3> 
  <table> 
   <thead> 
    <tr> 
     <th>参数</th> 
     <th>说明</th> 
    </tr> 
   </thead> 
   <tbody> 
    <tr> 
     <td>–prefix=</td> 
     <td>指向安装目录</td> 
    </tr> 
    <tr> 
     <td>–sbin-path</td> 
     <td>指向(执行)程序文件(nginx)</td> 
    </tr> 
    <tr> 
     <td>–conf-path=</td> 
     <td>指向配置文件(nginx.conf)</td> 
    </tr> 
    <tr> 
     <td>–error-log-path=</td> 
     <td>指向错误日志目录</td> 
    </tr> 
    <tr> 
     <td>–pid-path=</td> 
     <td>指向 pid 文件(nginx.pid)</td> 
    </tr> 
    <tr> 
     <td>–lock-path=</td> 
     <td>指向 lock 文件(nginx.lock)(安装文件锁定,防止安装文件被别人利用,或自己误操作。)</td> 
    </tr> 
    <tr> 
     <td>–user=</td> 
     <td>指定程序运行时的非特权用户</td> 
    </tr> 
    <tr> 
     <td>–group=</td> 
     <td>指定程序运行时的非特权用户组</td> 
    </tr> 
    <tr> 
     <td>–builddir=</td> 
     <td>指向编译目录</td> 
    </tr> 
    <tr> 
     <td>–with-rtsig_module</td> 
     <td>启用 rtsig 模块支持(实时信号)</td> 
    </tr> 
    <tr> 
     <td>–with-select_module</td> 
     <td>启用 select 模块支持(一种轮询模式,不推荐在高载环境下使用)禁用:–withoutselect_module</td> 
    </tr> 
    <tr> 
     <td>–with-poll_module</td> 
     <td>启用 poll 模块支持(功能与 select 相同,与 select 特性相同,为一种轮询模式,不推荐在高载环境下使用)</td> 
    </tr> 
    <tr> 
     <td>–with-file-aio</td> 
     <td>启用 file aio 支持(一种 APL 文件传输格式)</td> 
    </tr> 
    <tr> 
     <td>–with-ipv6</td> 
     <td>启用 ipv6 支持</td> 
    </tr> 
    <tr> 
     <td>–with-http_ssl_module</td> 
     <td>启用 ngx_http_ssl_module 支持(使支持 https 请求,需已安装 openssl)</td> 
    </tr> 
    <tr> 
     <td>–with-http_realip_module</td> 
     <td>启用 ngx_http_realip_module 支持(这个模块允许从请求标头更改客户端的 IP 地址值,默认为关)</td> 
    </tr> 
    <tr> 
     <td>–with-http_addition_module</td> 
     <td>启用 ngx_http_addition_module 支持(作为一个输出过滤器,支持不完全缓冲,分部分响应请求)</td> 
    </tr> 
    <tr> 
     <td>–with-http_xslt_module</td> 
     <td>启用 ngx_http_xslt_module 支持(过滤转换 XML 请求)</td> 
    </tr> 
    <tr> 
     <td>–with-http_image_filter_module</td> 
     <td>启用 ngx_http_image_filter_module 支持(传输 JPEG/GIF/PNG 图片的一个过滤器)(默认为不启用。gd 库要用到)</td> 
    </tr> 
    <tr> 
     <td>–with-http_geoip_module</td> 
     <td>启用 ngx_http_geoip_module 支持(该模块创建基于与 MaxMind GeoIP 二进制文件相配的客户端 IP 地址的 ngx_http_geoip_module 变量)</td> 
    </tr> 
    <tr> 
     <td>–with-http_sub_module</td> 
     <td>启用 ngx_http_sub_module 支持(允许用一些其他文本替换 nginx 响应中的一些文本)</td> 
    </tr> 
    <tr> 
     <td>–with-http_dav_module</td> 
     <td>启用 ngx_http_dav_module 支持(增加 PUT,DELETE,MKCOL:创建集合,COPY 和 MOVE 方法)默认情况下为关闭,需编译开启</td> 
    </tr> 
    <tr> 
     <td>–with-http_flv_module</td> 
     <td>启用 ngx_http_flv_module 支持(提供寻求内存使用基于时间的偏移量文件)</td> 
    </tr> 
    <tr> 
     <td>–with-http_gzip_static_module</td> 
     <td>启用 ngx_http_gzip_static_module 支持(在线实时压缩输出数据流)</td> 
    </tr> 
    <tr> 
     <td>–with-http_random_index_module</td> 
     <td>启用 ngx_http_random_index_module 支持(从目录中随机挑选一个目录索引)</td> 
    </tr> 
    <tr> 
     <td>–with-http_secure_link_module</td> 
     <td>启用 ngx_http_secure_link_module 支持(计算和检查要求所需的安全链接网址)</td> 
    </tr> 
    <tr> 
     <td>–with-http_degradation_module</td> 
     <td>启用 ngx_http_degradation_module 支持(允许在内存不足的情况下返回204 或 444 码)</td> 
    </tr> 
    <tr> 
     <td>–with-http_stub_status_module</td> 
     <td>启用 ngx_http_stub_status_module 支持(获取 nginx 自上次启动以来的工作状态)</td> 
    </tr> 
    <tr> 
     <td>–without-http_charset_module</td> 
     <td>禁用 ngx_http_charset_module 支持(重新编码 web 页面,但只能是一个方向–服务器端到客户端,并且只有一个字节的编码可以被重新编码)</td> 
    </tr> 
    <tr> 
     <td>–without-http_gzip_module</td> 
     <td>禁用 ngx_http_gzip_module 支持(该模块同-with-http_gzip_static_module 功能一样)</td> 
    </tr> 
    <tr> 
     <td>–without-http_ssi_module</td> 
     <td>禁用 ngx_http_ssi_module 支持(该模块提供了一个在输入端处理处理服务器包含文件(SSI)的过滤器,目前支持 SSI 命令的列表是不完整的)</td> 
    </tr> 
    <tr> 
     <td>–without-http_userid_module</td> 
     <td>禁用 ngx_http_userid_module 支持(该模块用来处理用来确定客户端后续请求的 cookies)</td> 
    </tr> 
    <tr> 
     <td>–without-http_access_module</td> 
     <td>禁用 ngx_http_access_module 支持(该模块提供了一个简单的基于主机的访问控制。允许/拒绝基于 ip 地址)</td> 
    </tr> 
    <tr> 
     <td>–without-http_auth_basic_module</td> 
     <td>禁用 ngx_http_auth_basic_module(该模块是可以使用用户名和密码基于http 基本认证方法来保护你的站点或其部分内容)</td> 
    </tr> 
    <tr> 
     <td>–without-http_autoindex_module</td> 
     <td>禁用 disable ngx_http_autoindex_module 支持(该模块用于自动生成目录列表,只在 ngx_http_index_module 模块未找到索引文件时发出请求。)</td> 
    </tr> 
    <tr> 
     <td>–without-http_geo_module</td> 
     <td>禁用 ngx_http_geo_module 支持(创建一些变量,其值依赖于客户端的 IP 地址)</td> 
    </tr> 
    <tr> 
     <td>–without-http_map_module</td> 
     <td>禁用 ngx_http_map_module 支持(使用任意的键/值对设置配置变量)</td> 
    </tr> 
    <tr> 
     <td>–without-http_split_clients_module</td> 
     <td>禁用 ngx_http_split_clients_module 支持(该模块用来基于某些条件划分用户。条件如:ip 地址、报头、cookies 等等)</td> 
    </tr> 
    <tr> 
     <td>–without-http_referer_module</td> 
     <td>禁用 disable ngx_http_referer_module 支持(该模块用来过滤请求,拒绝报头中 Referer 值不正确的请求)</td> 
    </tr> 
    <tr> 
     <td>–without-http_rewrite_module</td> 
     <td>禁用 ngx_http_rewrite_module 支持(该模块允许使用正则表达式改变 URI,并且根据变量来转向以及选择配置。如果在 server 级别设置该选项,那么他们将在 location 之前生效。如果在location 还有更进一步的重写规则,location 部分的规则依然会被执行。如果这个 URI 重写是因为 location 部分的规则造成的,那么 location 部分会再次被执行作为新的 URI。 这个循环会执行 10 次,然后 Nginx 会返回一个 500 错误。)</td> 
    </tr> 
    <tr> 
     <td>–without-http_proxy_module</td> 
     <td>禁用 ngx_http_proxy_module 支持(有关代理服务器)</td> 
    </tr> 
    <tr> 
     <td>–without-http_fastcgi_module</td> 
     <td>禁用 ngx_http_fastcgi_module 支持(该模块允许 Nginx 与 FastCGI 进程交互,并通过传递参数来控制 FastCGI 进程工作。 )FastCGI 一个常驻型的公共网关接口。</td> 
    </tr> 
    <tr> 
     <td>–without-http_uwsgi_module</td> 
     <td>禁用 ngx_http_uwsgi_module 支持(该模块用来医用 uwsgi 协议,uWSGI 服务器相关)</td> 
    </tr> 
    <tr> 
     <td>–without-http_scgi_module</td> 
     <td>禁用 ngx_http_scgi_module 支持(该模块用来启用 SCGI 协议支持,SCGI 协议是CGI 协议的替代。它是一种应用程序与 HTTP 服务接口标准。它有些像 FastCGI 但他的设计 更容易实现。)</td> 
    </tr> 
    <tr> 
     <td>–without-http_memcached_module</td> 
     <td>禁用 ngx_http_memcached_module 支持(该模块用来提供简单的缓存,以提高系统效率)</td> 
    </tr> 
    <tr> 
     <td>-without-http_limit_zone_module</td> 
     <td>禁用 ngx_http_limit_zone_module 支持(该模块可以针对条件,进行会话的并发连接数控制)</td> 
    </tr> 
    <tr> 
     <td>–without-http_limit_req_module</td> 
     <td>禁用 ngx_http_limit_req_module 支持(该模块允许你对于一个地址进行请求数量的限制用一个给定的 session 或一个特定的事件)</td> 
    </tr> 
    <tr> 
     <td>–without-http_empty_gif_module</td> 
     <td>禁用 ngx_http_empty_gif_module 支持(该模块在内存中常驻了一个 1*1 的透明 GIF 图像,可以被非常快速的调用)</td> 
    </tr> 
    <tr> 
     <td>–without-http_browser_module</td> 
     <td>禁用 ngx_http_browser_module 支持(该模块用来创建依赖于请求报头的值。如果浏览器为 modern ,则$modern_browser 等于 modern_browser_value 指令分配的值;如 果浏览器为 old,则$ancient_browser 等于 ancient_browser_value 指令分配的值;如果浏览器为 MSIE 中的任意版本,则 $msie 等于 1)</td> 
    </tr> 
    <tr> 
     <td>–without-http_upstream_ip_hash_module</td> 
     <td>禁用 ngx_http_upstream_ip_hash_module 支持(该模块用于简单的负载均衡)</td> 
    </tr> 
    <tr> 
     <td>–with-http_perl_module</td> 
     <td>启用 ngx_http_perl_module 支持(该模块使 nginx 可以直接使用 perl 或通过 ssi 调用 perl)</td> 
    </tr> 
    <tr> 
     <td>–with-perl_modules_path=</td> 
     <td>设定 perl 模块路径</td> 
    </tr> 
    <tr> 
     <td>–with-perl=</td> 
     <td>设定 perl 库文件路径</td> 
    </tr> 
    <tr> 
     <td>–http-log-path=</td> 
     <td>设定 access log 路径</td> 
    </tr> 
    <tr> 
     <td>–http-client-body-temp-path=</td> 
     <td>设定 http 客户端请求临时文件路径</td> 
    </tr> 
    <tr> 
     <td>–http-proxy-temp-path=</td> 
     <td>设定 http 代理临时文件路径</td> 
    </tr> 
    <tr> 
     <td>–http-fastcgi-temp-path=</td> 
     <td>设定 http fastcgi 临时文件路径</td> 
    </tr> 
    <tr> 
     <td>–http-uwsgi-temp-path=</td> 
     <td>设定 http uwsgi 临时文件路径</td> 
    </tr> 
    <tr> 
     <td>–http-scgi-temp-path=</td> 
     <td>设定 http scgi 临时文件路径</td> 
    </tr> 
    <tr> 
     <td>-without-http</td> 
     <td>禁用 http server 功能</td> 
    </tr> 
    <tr> 
     <td>–without-http-cache</td> 
     <td>禁用 http cache 功能</td> 
    </tr> 
    <tr> 
     <td>–with-mail</td> 
     <td>启用 POP3/IMAP4/SMTP 代理模块支持</td> 
    </tr> 
    <tr> 
     <td>–with-mail_ssl_module</td> 
     <td>启用 ngx_mail_ssl_module 支持</td> 
    </tr> 
    <tr> 
     <td>–without-mail_pop3_module</td> 
     <td>禁用 pop3 协议(POP3 即邮局协议的第 3 个版本,它是规定个人计算机如何连接到互联网上的邮件服务器进行收发邮件的协议。是因特网电子邮件的第一个离线协议标 准,POP3 协议允许用户从服务器上把邮件存储到本地主机上,同时根据客户端的操作删除或保存在邮件服务器上的邮件。POP3 协议是 TCP/IP 协议族中的一员,主要用于 支持使用客户端远程管理在服务器上的电子邮件)</td> 
    </tr> 
    <tr> 
     <td>–without-mail_imap_module</td> 
     <td>禁用 imap 协议(一种邮件获取协议。它的主要作用是邮件客户端可以通过这种协议从邮件服务器上获取邮件的信息,下载邮件等。IMAP 协议运行在 TCP/IP 协议之上, 使用的端口是 143。它与POP3 协议的主要区别是用户可以不用把所有的邮件全部下载,可以通过客户端直接对服务器上的邮件进行操作。)</td> 
    </tr> 
    <tr> 
     <td>–without-mail_smtp_module</td> 
     <td>禁用 smtp 协议(SMTP 即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。SMTP 协议属于 TCP/IP 协议族,它帮助每台计算机在发送或中转信件时找到下一个目的地。)</td> 
    </tr> 
    <tr> 
     <td>–with-google_perftools_module</td> 
     <td>启用 ngx_google_perftools_module 支持(调试用,剖析程序性能瓶颈)</td> 
    </tr> 
    <tr> 
     <td>–with-cpp_test_module</td> 
     <td>启用 ngx_cpp_test_module 支持</td> 
    </tr> 
    <tr> 
     <td>–add-module=</td> 
     <td>启用外部模块支持</td> 
    </tr> 
    <tr> 
     <td>–with-cc=</td> 
     <td>指向 C 编译器路径</td> 
    </tr> 
    <tr> 
     <td>–with-cpp=</td> 
     <td>指向 C 预处理路径</td> 
    </tr> 
    <tr> 
     <td>–with-cc-opt=</td> 
     <td>设置 C 编译器参数(PCRE 库,需要指定–with-cc-opt=”-I /usr/local/include”,如果使用select()函数则需要同时增加文件描述符数量,可以通过–with-cc- opt=”-D FD_SETSIZE=2048”指定。)</td> 
    </tr> 
    <tr> 
     <td>–with-ld-opt=</td> 
     <td>设置连接文件参数。(PCRE 库,需要指定–with-ld-opt=”-L /usr/local/lib”。)</td> 
    </tr> 
    <tr> 
     <td>–with-cpu-opt=</td> 
     <td>指定编译的 CPU,可用的值为: pentium, pentiumpro, pentium3, pentium4, athlon, opteron, amd64, sparc32, sparc64, ppc64</td> 
    </tr> 
    <tr> 
     <td>–without-pcre</td> 
     <td>禁用 pcre 库</td> 
    </tr> 
    <tr> 
     <td>–with-pcre</td> 
     <td>启用 pcre 库</td> 
    </tr> 
    <tr> 
     <td>–with-pcre=</td> 
     <td>指向 pcre 库文件目录</td> 
    </tr> 
    <tr> 
     <td>–with-pcre-opt=</td> 
     <td>在编译时为 pcre 库设置附加参数</td> 
    </tr> 
    <tr> 
     <td>–with-md5=</td> 
     <td>指向 md5 库文件目录(消息摘要算法第五版,用以提供消息的完整性保护)</td> 
    </tr> 
    <tr> 
     <td>–with-md5-opt=</td> 
     <td>在编译时为 md5 库设置附加参数</td> 
    </tr> 
    <tr> 
     <td>–with-md5-asm</td> 
     <td>使用 md5 汇编源</td> 
    </tr> 
    <tr> 
     <td>–with-sha1=</td> 
     <td>指向 sha1 库目录(数字签名算法,主要用于数字签名)</td> 
    </tr> 
    <tr> 
     <td>–with-sha1-opt=</td> 
     <td>在编译时为 sha1 库设置附加参数</td> 
    </tr> 
    <tr> 
     <td>–with-sha1-asm</td> 
     <td>使用 sha1 汇编源</td> 
    </tr> 
    <tr> 
     <td>–with-zlib=</td> 
     <td>指向 zlib 库目录</td> 
    </tr> 
    <tr> 
     <td>–with-zlib-opt=</td> 
     <td>在编译时为 zlib 设置附加参数</td> 
    </tr> 
    <tr> 
     <td>–with-zlib-asm=</td> 
     <td>为指定的 CPU 使用 zlib 汇编源进行优化,CPU 类型为 pentium, pentiumpro</td> 
    </tr> 
    <tr> 
     <td>–with-libatomic</td> 
     <td>为原子内存的更新操作的实现提供一个架构</td> 
    </tr> 
    <tr> 
     <td>–with-libatomic=</td> 
     <td>指向 libatomic_ops 安装目录</td> 
    </tr> 
    <tr> 
     <td>–with-openssl=</td> 
     <td>指向 openssl 安装目录</td> 
    </tr> 
    <tr> 
     <td>–with-openssl-opt</td> 
     <td>在编译时为 openssl 设置附加参数</td> 
    </tr> 
    <tr> 
     <td>–with-debug</td> 
     <td>启用 debug 日志</td> 
    </tr> 
   </tbody> 
  </table> 
  <h3>附录B</h3> 
  <h5>Rewrite常用全局变量</h5> 
  <table> 
   <thead> 
    <tr> 
     <th>参数</th> 
     <th>注释</th> 
    </tr> 
   </thead> 
   <tbody> 
    <tr> 
     <td>$arg_PARAMETER</td> 
     <td>HTTP 请求中某个参数的值,如/index?site=www.ttlsa.com,可以用$arg_site 取得 www.ttlsa.com 这个值</td> 
    </tr> 
    <tr> 
     <td>$ args:</td> 
     <td>变量中存放了请求URL中的请求指令。比如http://192.168.200.133:8080?arg1=value1&args2=value2中 的"arg1=value1&arg2=value2",功能和$query_string一样</td> 
    </tr> 
    <tr> 
     <td>$http_user_agent:</td> 
     <td>变量存储的是用户访问服务的代理信息(如果通过浏览器访问,记录的是浏览器的相关版本信息)</td> 
    </tr> 
    <tr> 
     <td>$host :</td> 
     <td>变量存储的是访问服务器的server_name值</td> 
    </tr> 
    <tr> 
     <td>$hostname</td> 
     <td>表示 Nginx 所在机器的名称,与 gethostbyname 调用返回的值相同</td> 
    </tr> 
    <tr> 
     <td>$uri</td> 
     <td>表示当前请求的 URI,不带任何参数</td> 
    </tr> 
    <tr> 
     <td>$ document_uri :</td> 
     <td>变量存储的是当前访问地址的URI。比如http://192.168.200.133/server?id=10&name=zhangsan中的"/server",功能和$uri一样</td> 
    </tr> 
    <tr> 
     <td>$document_root:</td> 
     <td>变量存储的是当前请求对应location的root值,如果未设置,默认指向Nginx自带html目录所在位置</td> 
    </tr> 
    <tr> 
     <td>$body_bytes_sent</td> 
     <td>表示在向客户端发送的 http 响应中,包体部分的字节数</td> 
    </tr> 
    <tr> 
     <td>$content_length :</td> 
     <td>变量存储的是请求头中的Content-Length的 值</td> 
    </tr> 
    <tr> 
     <td>$content_type :</td> 
     <td>变量存储的是请求头中的Content-Type的值</td> 
    </tr> 
    <tr> 
     <td>$cookie_COOKIE</td> 
     <td>表示在客户端请求头部中的 cookie 字段</td> 
    </tr> 
    <tr> 
     <td>$http_HEADER</td> 
     <td>表示当前 HTTP 请求中相应头部的值。HEADER 名称全小写。例如,示请求中 Host 头部对应的值 用 $http_host 表</td> 
    </tr> 
    <tr> 
     <td>$http_cookie :</td> 
     <td>变量存储的是客户端的cookie信息,可以通过add_header Set-Cookie 'cookieName=cookieValue’来添加cookie数 据</td> 
    </tr> 
    <tr> 
     <td>$sent_http_HEADER</td> 
     <td>表示返回客户端的 HTTP 响应中相应头部的值。HEADER 名称全小写。例如,用 $sent_ http_content_type 表示响应中 Content-Type 头部对应的值</td> 
    </tr> 
    <tr> 
     <td>$is_args</td> 
     <td>表示请求中的 URI 是否带参数,如果带参数,$is_args 值为 ?,如果不带参数,则是空字符串</td> 
    </tr> 
    <tr> 
     <td>$limit_rate :</td> 
     <td>变量中存储的是Nginx服务器对网络连接速率的限制,也就是Nginx配置中对limit_rate指令设置的值,默认是0,不限制。</td> 
    </tr> 
    <tr> 
     <td>$nginx_version</td> 
     <td>表示当前 Nginx 的版本号</td> 
    </tr> 
    <tr> 
     <td>$query_string</td> 
     <td>请求 URI 中的参数,与 $args 相同,然而 $query_string 是只读的不会改变</td> 
    </tr> 
    <tr> 
     <td>$remote_addr :</td> 
     <td>变量中存储的是客户端的IP地址</td> 
    </tr> 
    <tr> 
     <td>$remote_port :</td> 
     <td>变量中存储了客户端与服务端建立连接的端口号</td> 
    </tr> 
    <tr> 
     <td>$remote_user :</td> 
     <td>变量中存储了客户端的用户名,需要有认证模块才能获取</td> 
    </tr> 
    <tr> 
     <td>$scheme</td> 
     <td>变量中存储了访问协议</td> 
    </tr> 
    <tr> 
     <td>$server_addr</td> 
     <td>变量中存储了服务端的地址</td> 
    </tr> 
    <tr> 
     <td>$server_name</td> 
     <td>变量中存储了客户端请求到达的服务器的名称</td> 
    </tr> 
    <tr> 
     <td>$server_port</td> 
     <td>变量中存储了客户端请求到达服务器的端口号</td> 
    </tr> 
    <tr> 
     <td>$server_protocol</td> 
     <td>变量中存储了客户端请求协议的版本,比如"HTTP/1.1"</td> 
    </tr> 
    <tr> 
     <td>$request_body</td> 
     <td>表示 HTTP 请求中的包体,该参数只在 proxy_pass 或 fastcgi_pass 中有意义</td> 
    </tr> 
    <tr> 
     <td>$request_body_file</td> 
     <td>变量中存储了发给后端服务器的本地文件资源的名称</td> 
    </tr> 
    <tr> 
     <td>$request_completion</td> 
     <td>当请求已经全部完成时,其值为 “ok”。若没有完成,就要返回客户端,则其值为空字符串;或者在断点续传等情况下使用 HTTP range 访问的并不是文件的最后一块,那么其值也是空字符串。</td> 
    </tr> 
    <tr> 
     <td>$request_method</td> 
     <td>变量中存储了客户端的请求方式,比如"GET","POST"等</td> 
    </tr> 
    <tr> 
     <td>$request_filename</td> 
     <td>变量中存储了当前请求的资源文件的路径名</td> 
    </tr> 
    <tr> 
     <td>$request_uri :</td> 
     <td>变量中存储了当前请求的URI,并且携带请求参数,比如http://192.168.200.133/server?id=10&name=zhangsan中的"/server?id=10&name=zhangsan"</td> 
    </tr> 
   </tbody> 
  </table> 
 </div> 
</div>
                            </div>
                        </div>
                    </div>
                    <!--PC和WAP自适应版-->
                    <div id="SOHUCS" sid="1759467306716573696"></div>
                    <script type="text/javascript" src="/views/front/js/chanyan.js"></script>
                    <!-- 文章页-底部 动态广告位 -->
                    <div class="youdao-fixed-ad" id="detail_ad_bottom"></div>
                </div>
                <div class="col-md-3">
                    <div class="row" id="ad">
                        <!-- 文章页-右侧1 动态广告位 -->
                        <div id="right-1" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad">
                            <div class="youdao-fixed-ad" id="detail_ad_1"> </div>
                        </div>
                        <!-- 文章页-右侧2 动态广告位 -->
                        <div id="right-2" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad">
                            <div class="youdao-fixed-ad" id="detail_ad_2"></div>
                        </div>
                        <!-- 文章页-右侧3 动态广告位 -->
                        <div id="right-3" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad">
                            <div class="youdao-fixed-ad" id="detail_ad_3"></div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div class="container">
        <h4 class="pt20 mb15 mt0 border-top">你可能感兴趣的:(软件配置与环境搭建,读后感,架构,nginx,运维,服务器)</h4>
        <div id="paradigm-article-related">
            <div class="recommend-post mb30">
                <ul class="widget-links">
                    <li><a href="/article/1773611795592839168.htm"
                           title="《昼颜》里的日本女人:相遇要万种风情,分手要残忍绝情" target="_blank">《昼颜》里的日本女人:相遇要万种风情,分手要残忍绝情</a>
                        <span class="text-muted">迷影咖啡</span>

                        <div>作者:迷之菌子神奇菇迷影咖啡:一本正经做烘焙,胡说八道聊电影漫天萤火虫消散之时良宵就将过去,人们也说含苞待放的花蕾总会开了又谢,因紧紧相拥而面红耳赤的躯体,便是我们经历过这热爱的证明。夫妻关系介绍《昼颜》是2014年电视剧《昼颜:工作日下午三点的恋人们》的续集,故事发在电视剧情节结束的三年后,讲述了已经恢复独身的纱和偶然与曾经的出轨对象北野重逢后再次陷入感情漩涡的故事。《昼颜》制作灵感源自利佳子在</div>
                    </li>
                    <li><a href="/article/1773611668312489984.htm"
                           title="迎接2019" target="_blank">迎接2019</a>
                        <span class="text-muted">唯有杜康1994</span>

                        <div>告别2018这一年是机遇与挑战,痛苦与喜悦,失去与收获的一年一月:收获了第一份爱情,开始真正想去了解一个人三月:对工作有了更深入的认识,靠自己的力量完成晋升五月:搬家,住进了自己理想的公寓,一间属于自己的屋子。满地的书六月:外调广州,升经理,有了自己的第一个团队。七月:怀着自我否定,第一次完成了部门任务八月:第一个员工流失,痛哭不已明白无不散之筵席九月:员工陆续离开,经济是一切的根本。十月:陪员工</div>
                    </li>
                    <li><a href="/article/1773606223896182784.htm"
                           title="极狐GitLab 论坛 2.0 全新上线,可以在论坛上查找与 GitLab 相关的问题了~" target="_blank">极狐GitLab 论坛 2.0 全新上线,可以在论坛上查找与 GitLab 相关的问题了~</a>
                        <span class="text-muted">极小狐</span>
<a class="tag" taget="_blank" href="/search/gitlab/1.htm">gitlab</a><a class="tag" taget="_blank" href="/search/%E6%9E%81%E7%8B%90GitLab/1.htm">极狐GitLab</a><a class="tag" taget="_blank" href="/search/devops/1.htm">devops</a><a class="tag" taget="_blank" href="/search/GitLab/1.htm">GitLab</a><a class="tag" taget="_blank" href="/search/ci%2Fcd/1.htm">ci/cd</a><a class="tag" taget="_blank" href="/search/devsecops/1.htm">devsecops</a><a class="tag" taget="_blank" href="/search/SCM/1.htm">SCM</a>
                        <div>安装出现依赖错误?版本升级搞不定?遇到422、500就懵逼了?不知道某个功能是免费or付费?……使用GitLab这种全球顶级的DevOps平台进行软件研发时,总会遇到一些困惑,想跟专业的技术人员快速交流以便获得答案,同时又想把这些问题沉淀下来以帮助他人?有这种赠人玫瑰,手有余香的解决方案吗?答案肯定有:论坛!!!论坛——一个各路大神聚集的地方,一个可以解惑答疑问道的地方。解惑:搜索与自己问题相同或</div>
                    </li>
                    <li><a href="/article/1773604729713131520.htm"
                           title="我喝醉了,但是与你无关" target="_blank">我喝醉了,但是与你无关</a>
                        <span class="text-muted">Z先生的日记本</span>

                        <div>2019年04月10号晚上我和一个朋友喝酒了,彻彻底底的喝醉了,喝到短片,事后我问L,我说我喝醉了之后,都发生了什么,L没有告诉我详情,但是跟我说了大致,他说我跟他一直聊天,说自己小的时候的事,说自己爸妈的事,说自己现在过得很苦可能,确实是喝醉了酒,才会毫无防备的跟其他人说这些吧。L还说感觉我过得很苦,很心疼。醉了酒之后还哭了,想想还真是丢人一年前,在宿舍也有一瓶红酒,那是舍友出去拉赞助时候,友商</div>
                    </li>
                    <li><a href="/article/1773604712310964224.htm"
                           title="python抓包与解包_Python—网络抓包与解包(pcap、dpkt)" target="_blank">python抓包与解包_Python—网络抓包与解包(pcap、dpkt)</a>
                        <span class="text-muted">weixin_39691055</span>
<a class="tag" taget="_blank" href="/search/python%E6%8A%93%E5%8C%85%E4%B8%8E%E8%A7%A3%E5%8C%85/1.htm">python抓包与解包</a>
                        <div>pcap安装[root@localhost~]#pipinstallpypcap抓包与解包#-*-coding:utf-8-*-importpcap,dpktimportre,threading,requests__black_ip=['103.224.249.123','203.66.1.212']#抓包:param1eth_name网卡名,如:eth0,eth3。param2p_type日志捕</div>
                    </li>
                    <li><a href="/article/1773603578330546176.htm"
                           title="Flink中的SQL Client和SQL Gateway" target="_blank">Flink中的SQL Client和SQL Gateway</a>
                        <span class="text-muted">BigDataMLApplication</span>
<a class="tag" taget="_blank" href="/search/flink/1.htm">flink</a><a class="tag" taget="_blank" href="/search/flink/1.htm">flink</a><a class="tag" taget="_blank" href="/search/sql/1.htm">sql</a><a class="tag" taget="_blank" href="/search/gateway/1.htm">gateway</a>
                        <div>Flink中的SQLClient和SQLGateway对比目录定义基本原理适用场景主要区别常用运维命令示例官方链接正文1.定义SQLClient:FlinkSQLClient是一种用于提交和执行FlinkSQL语句的命令行界面或图形界面工具。SQLGateway:FlinkSQLGateway是一个独立的服务,它允许客户端通过RESTfulAPI将SQL查询提交到Flink集群。2.基本原理SQL</div>
                    </li>
                    <li><a href="/article/1773603579169406976.htm"
                           title="2022年河南省高等职业教育技能大赛云计算赛项竞赛赛卷(样卷)" target="_blank">2022年河南省高等职业教育技能大赛云计算赛项竞赛赛卷(样卷)</a>
                        <span class="text-muted">忘川_ydy</span>
<a class="tag" taget="_blank" href="/search/%E4%BA%91%E8%AE%A1%E7%AE%97/1.htm">云计算</a><a class="tag" taget="_blank" href="/search/%E4%BA%91%E8%AE%A1%E7%AE%97/1.htm">云计算</a><a class="tag" taget="_blank" href="/search/openstack/1.htm">openstack</a><a class="tag" taget="_blank" href="/search/kubernetes/1.htm">kubernetes</a><a class="tag" taget="_blank" href="/search/docker/1.htm">docker</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/k8s/1.htm">k8s</a><a class="tag" taget="_blank" href="/search/ansible/1.htm">ansible</a>
                        <div>#需要资源(软件包及镜像)或有问题的,可私博主!!!#需要资源(软件包及镜像)或有问题的,可私博主!!!#需要资源(软件包及镜像)或有问题的,可私博主!!!第一部分:私有云任务1私有云服务搭建(10分)使用提供的用户名密码,登录竞赛用的云计算平台,按要求自行使用镜像创建两台云主机,创建完云主机后确保网络正常通信,然后按要求配置服务器。根据提供安装脚本框架,补充脚本完成OpenStack平台的安装搭</div>
                    </li>
                    <li><a href="/article/1773602697044361216.htm"
                           title="浪潮 M5系列服务器IPMI无法监控存储RAID卡问题." target="_blank">浪潮 M5系列服务器IPMI无法监控存储RAID卡问题.</a>
                        <span class="text-muted">Songxwn</span>
<a class="tag" taget="_blank" href="/search/%E7%A1%AC%E4%BB%B6%E6%9C%8D%E5%8A%A1%E5%99%A8/1.htm">硬件服务器</a><a class="tag" taget="_blank" href="/search/%E6%9C%8D%E5%8A%A1%E5%99%A8/1.htm">服务器</a><a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a>
                        <div>简介浪潮的M5代服务器,可能有WebBMC无法查看存储RAID/SAS卡状态的情况,可以通过以下方式修改。修改完成后重启BMC即可生效。ESXiIPMITools使用:https://songxwn.com/ESXi8_IPMI/(Linux也可以直接使用)Linux/ESXiIPMITool下载:https://songxwn.com/file/ipmitoolWindows下载:https:/</div>
                    </li>
                    <li><a href="/article/1773596671511429120.htm"
                           title="拼多多纸巾推荐:品质与性价比的完美结合" target="_blank">拼多多纸巾推荐:品质与性价比的完美结合</a>
                        <span class="text-muted">氧惠帮朋友一起省</span>

                        <div>拼多多纸巾推荐拼多多纸巾返现怎么做在我们的日常生活中,纸巾已经成为不可或缺的用品。无论是在家庭、办公室还是旅途中,纸巾都是我们随时随地需要的物品。随着电商平台的兴起,越来越多的人选择在网上购买纸巾。其中,拼多多作为国内知名的电商平台之一,以其独特的社交电商模式和实惠的价格吸引了大量用户。今天,我们就来探讨如何在拼多多上选择品质优良、性价比高的纸巾,以及如何通过一些小技巧来获取更多的优惠。一、品质与</div>
                    </li>
                    <li><a href="/article/1773594136444731392.htm"
                           title="word字号和mathtype磅值关系及批量修改" target="_blank">word字号和mathtype磅值关系及批量修改</a>
                        <span class="text-muted">小铁匠-Ma</span>
<a class="tag" taget="_blank" href="/search/office%E5%B0%8F%E6%8A%80%E5%B7%A7/1.htm">office小技巧</a><a class="tag" taget="_blank" href="/search/%E7%BB%8F%E9%AA%8C%E5%88%86%E4%BA%AB/1.htm">经验分享</a>
                        <div>word字号和mathtype磅值关系及批量修改1.字号与磅值关系字号「八号」对应磅值5字号「七号」对应磅值5.5字号「小六」对应磅值6.5字号「六号」对应磅值7.5字号「小五」对应磅值9字号「五号」对应磅值10.5字号「小四」对应磅值12字号「四号」对应磅值14字号「小三」对应磅值15字号「三号」对应磅值16字号「小二」对应磅值18字号「二号」对应磅值22字号「小一」对应磅值24字号「一号」对应</div>
                    </li>
                    <li><a href="/article/1773588094755340288.htm"
                           title="美团自动配送车2024春季招聘 | 社招专场" target="_blank">美团自动配送车2024春季招聘 | 社招专场</a>
                        <span class="text-muted">美团技术团队</span>

                        <div>关于美团自动配送团队美团自动配送以自研L4级自动驾驶软硬件技术为核心,与美团即时零售业务结合,形成满足公开道路、校园、社区、工业园区等室外全场景下的自动配送整体解决方案。美团自动配送团队成立于2016年,团队成员来自于Waymo、Cruise、Pony.ai、泛亚等自动驾驶行业头部公司,自动驾驶技术团队博士占比高达30%,依靠视觉、激光等传感器,实时感知预测周围环境,通过高精地图定位和智能决策规划</div>
                    </li>
                    <li><a href="/article/1773579033229983744.htm"
                           title="php 把一个数组分成有n个元素的二维数组的算法" target="_blank">php 把一个数组分成有n个元素的二维数组的算法</a>
                        <span class="text-muted">风清扬-独孤九剑</span>
<a class="tag" taget="_blank" href="/search/php/1.htm">php</a><a class="tag" taget="_blank" href="/search/php/1.htm">php</a><a class="tag" taget="_blank" href="/search/%E7%AE%97%E6%B3%95/1.htm">算法</a>
                        <div>一、第一种解法0){$columns_map[$position]++;//这个地方格外注意,$position与$columns比较$position=($position<$columns-1)?++$position:0;$array_length--;}foreach($columns_mapas$val){$newarray[]=array_splice($array,0,$val);}</div>
                    </li>
                    <li><a href="/article/1773576508988784640.htm"
                           title="花气袭人知昼暖" target="_blank">花气袭人知昼暖</a>
                        <span class="text-muted">柒侠传</span>

                        <div>花气袭人知昼暖高一七班黄韵熹37号花袭人,原名花珍珠,位列金陵十二钗又副册中的第二位。“袭人”这一称呼源于“花气袭人知昼暖”这一诗句,是宝玉给起的。想起来便觉得暖融融的,一如花袭人温柔的笑容。但花袭人着实是令人又爱又怕的角色。第二十一回的回目将她赞作“贤袭人”,脂砚斋在一旁批道“当得起”。花袭人对宝玉的确是一片真心。她为劝宝玉收敛他那成日在大观园里与姐姐妹妹“厮混”的性子,假借家人赎回的机会,软语</div>
                    </li>
                    <li><a href="/article/1773576128875790336.htm"
                           title="你之所以胖,可能是因为小时候发生这件事!还不赶快甩锅" target="_blank">你之所以胖,可能是因为小时候发生这件事!还不赶快甩锅</a>
                        <span class="text-muted">周围_5d19</span>

                        <div>通常,我们认为,“肥胖”主要是由于饮食不节制、不经常运动等等因素引起的。但最近,我国学者开展的一项针对6到18岁儿童青少年、随访长达十年的代谢综合征研究结果,在权威国际期刊发表。研究发现,儿童的肥胖和超重与睡眠密切相关,儿童、青少年时期睡眠不好,成人后也更容易患心血管疾病。那么,为什么儿童青少年睡眠不足会导致肥胖呢?今天就带大家一探究竟。儿童青少年肥胖的现状如何?近日,一项刊载在医学权威期刊《柳叶</div>
                    </li>
                    <li><a href="/article/1773569718641295360.htm"
                           title="uni-app实现 步骤条" target="_blank">uni-app实现 步骤条</a>
                        <span class="text-muted">夏夏的码农</span>
<a class="tag" taget="_blank" href="/search/uni-app/1.htm">uni-app</a>
                        <div>实现如图样式html部分代码如下投资期限与收益0?'active':'default'">募集开始1?'active':'default'">募集结束2?'active':'default'">产品成立3?'active':'default'">产品到期0?'active-step1':'step1'">1?'active-st</div>
                    </li>
                    <li><a href="/article/1773565312734658560.htm"
                           title="【算法分析与设计】去除重复字母" target="_blank">【算法分析与设计】去除重复字母</a>
                        <span class="text-muted">五敷有你</span>
<a class="tag" taget="_blank" href="/search/%E7%AE%97%E6%B3%95%E5%88%86%E6%9E%90%E4%B8%8E%E8%AE%BE%E8%AE%A1/1.htm">算法分析与设计</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/javascript/1.htm">javascript</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a><a class="tag" taget="_blank" href="/search/%E7%AE%97%E6%B3%95/1.htm">算法</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/1.htm">数据结构</a>
                        <div>个人主页:五敷有你系列专栏:算法分析与设计⛺️稳中求进,晒太阳题目给你一个字符串s,请你去除字符串中重复的字母,使得每个字母只出现一次。需保证返回结果的字典序最小(要求不能打乱其他字符的相对位置)。示例示例1:输入:s="bcabc"输出:"abc"示例2:输入:s="cbacdcbc"输出:"acdb"思路贪心+单调栈实现【字符串删除一个字符使其字典序最小的贪心策略】:对于两个长度相同的字符串,</div>
                    </li>
                    <li><a href="/article/1773553941498363904.htm"
                           title="购物返利平台是真的吗" target="_blank">购物返利平台是真的吗</a>
                        <span class="text-muted">返金app平台高佣返利省钱</span>

                        <div>购物返利平台是真实存在的,它们提供一种通过购物来获取一定比例返现的服务。这些平台通常与商家合作,通过返利链接或其他追踪方式来追踪用户的购物行为,然后将一部分返现金额返还给用户。然而,需要注意的是,并非所有的购物返利平台都是可信的。在选择使用购物返利平台时,建议您注意以下几个方面:可信度和口碑:查看平台的用户评价和口碑,了解其他用户对该平台的使用体验和返利情况。合作商家:了解平台的合作商家是否可靠,</div>
                    </li>
                    <li><a href="/article/1773552600176721920.htm"
                           title="1.计算机处理器架构+嵌入式处理器架构及知识" target="_blank">1.计算机处理器架构+嵌入式处理器架构及知识</a>
                        <span class="text-muted">vv 啊</span>
<a class="tag" taget="_blank" href="/search/arm-linux%E5%AD%A6%E4%B9%A0/1.htm">arm-linux学习</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a><a class="tag" taget="_blank" href="/search/%E7%B3%BB%E7%BB%9F%E6%9E%B6%E6%9E%84/1.htm">系统架构</a>
                        <div>目录一:x86-64处理器架构二:Intel80386处理器(i386)1.i3862.i686三:嵌入式Linux知识:1.MinGW2.GNU计划2.1GNU工具链概述此次只分享英特尔和ADM处理器有关于x86的架构,至于嵌入式处理器架构请查看https://en.wikipedia.org/wiki/List_of_ARM_processors一:x86-64处理器架构x86-64,也称为x</div>
                    </li>
                    <li><a href="/article/1773528182234873856.htm"
                           title="springboot集成logback-spring.xml文件" target="_blank">springboot集成logback-spring.xml文件</a>
                        <span class="text-muted">RT_0114</span>
<a class="tag" taget="_blank" href="/search/SpringBoot/1.htm">SpringBoot</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/boot/1.htm">boot</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/logback/1.htm">logback</a>
                        <div>彩色日志日志分debug和error文件输出,方便开发人员运维日志限制最大保管天数日志限制总量大小占用量GB日志限制单个文件大小MB日志显示最大保留天数屏蔽没用的日志${CONSOLE_LOG_PATTERN}${log.path}/debug.log${log.path}/%d{yyyy-MM-dd,aux}/debug.%d{yyyy-MM-dd}.%i.log.gz1024MB50GB365</div>
                    </li>
                    <li><a href="/article/1773523649328906240.htm"
                           title="<商务世界>《第25课 餐桌上的礼仪-简单的流程》" target="_blank"><商务世界>《第25课 餐桌上的礼仪-简单的流程》</a>
                        <span class="text-muted">Ealser</span>
<a class="tag" taget="_blank" href="/search/%E5%95%86%E5%8A%A1%E4%B8%96%E7%95%8C/1.htm">商务世界</a><a class="tag" taget="_blank" href="/search/%E4%B8%AD%E5%9B%BD%E9%A4%90%E6%A1%8C%E7%A4%BC%E8%8A%82/1.htm">中国餐桌礼节</a>
                        <div>第一:迎客席座一般的程序是主人给客人邀请函——日子到了,主人到门外迎客——客人到了,问候几句——带着可人到0客厅小坐一会儿,给客人茶点——带客人入席坐好!第二:入座与座次首先要请客人中长者或地位高的先入座,再按身份地位依次入座,入座时要从椅子左边进入。(正对门口的为上座,一般是根据对方的.身份地位来安排)。入座后不要动筷子,更不要弄出什么响声来,也不要起身走动。如果有什么事要向主人打招呼!(做小辈</div>
                    </li>
                    <li><a href="/article/1773522055594049536.htm"
                           title="【美丽特色乡村】,景德镇马鞍岭村," target="_blank">【美丽特色乡村】,景德镇马鞍岭村,</a>
                        <span class="text-muted">粒子飞翔</span>

                        <div>【美丽特色乡村】,景德镇马鞍岭村,就像是陶渊明笔下的山水田园,阡陌交通,精美的白房参差错落,碧绿透亮的河水从不远处的深涧里连绵不绝流入此地,滋养着土里。成群的白鸭悠闲地在河水里戏水,人与环境达成和谐的境界。借助三宝国际瓷谷建设的契机,马鞍岭村迎来了天翻地覆的沧桑巨变,此地以陶瓷文化为特色,融合原来生态资源,修复了水碓遗址、矿坑遗址等历史文化遗产,提升生态环境现状。同时,依托三宝溪围绕整个村落,对河</div>
                    </li>
                    <li><a href="/article/1773521928447918080.htm"
                           title="2019.11.28感恩日记" target="_blank">2019.11.28感恩日记</a>
                        <span class="text-muted">afab5b74f713</span>

                        <div>1.感谢真我守护,一觉到天明,谢谢谢谢谢谢!2.感谢一大早,橘子就甩来4800的大红包,谢谢谢谢谢谢!3.感谢今天代理宝宝们疯狂加单,钱宝宝流入小十万,太牛了你们,有你们真好,谢谢谢谢谢谢!4.感谢自己拥有钱宝宝,可以去群里给宝宝们发红包,表达我的爱,谢谢谢谢谢谢钱宝宝爱我!5.感谢自己的细胞宝宝们,让我保持健康与活力,可以自由活动,活力满满,谢谢谢谢谢谢!6.感谢芬姐甩来订单,谢谢谢谢谢谢钱宝宝</div>
                    </li>
                    <li><a href="/article/1773510684068347904.htm"
                           title="请简单介绍一下Shiro框架是什么?Shiro在Java安全领域的主要作用是什么?Shiro主要提供了哪些安全功能?" target="_blank">请简单介绍一下Shiro框架是什么?Shiro在Java安全领域的主要作用是什么?Shiro主要提供了哪些安全功能?</a>
                        <span class="text-muted">AaronWang94</span>
<a class="tag" taget="_blank" href="/search/shiro/1.htm">shiro</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E5%AE%89%E5%85%A8/1.htm">安全</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a>
                        <div>请简单介绍一下Shiro框架是什么?Shiro框架是一个强大且灵活的开源安全框架,为Java应用程序提供了全面的安全解决方案。它主要用于身份验证、授权、加密和会话管理等功能,可以轻松地集成到任何JavaWeb应用程序中,并提供了易于理解和使用的API,使开发人员能够快速实现安全特性。Shiro的核心组件包括Subject、SecurityManager和Realms。Subject代表了当前与应用</div>
                    </li>
                    <li><a href="/article/1773504261557125120.htm"
                           title="谷歌浏览器驱动Chromedriver(114-120版本)文件以及驱动下载教程" target="_blank">谷歌浏览器驱动Chromedriver(114-120版本)文件以及驱动下载教程</a>
                        <span class="text-muted">pigerr杨</span>
<a class="tag" taget="_blank" href="/search/Python/1.htm">Python</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/chrome/1.htm">chrome</a><a class="tag" taget="_blank" href="/search/drivers/1.htm">drivers</a>
                        <div>ChromeDriver官方网站GitHub||GoogleChromeLabs/chrome-for-testingChromeDriver113-125_JSONChromeforTestingavailability123-125zip白月黑羽Python基础|进阶|Qt图形界面|Django|自动化测试|性能测试|JS语言|JS前端|原理与安装</div>
                    </li>
                    <li><a href="/article/1773504260386914304.htm"
                           title="通俗易懂:什么是Java虚拟机(JVM)?它的主要作用是什么?" target="_blank">通俗易懂:什么是Java虚拟机(JVM)?它的主要作用是什么?</a>
                        <span class="text-muted">大龄下岗程序员</span>
<a class="tag" taget="_blank" href="/search/mysql/1.htm">mysql</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/mysql/1.htm">mysql</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a>
                        <div>Java虚拟机(JavaVirtualMachine,JVM)是一种软件实现的抽象计算机,它负责执行Java字节码(Bytecode)。Java程序并不是直接在物理计算机上运行,而是先由Java编译器将源代码编译成与平台无关的字节码,然后由JVM负责读取字节码并在实际硬件架构上运行。JVM的主要作用包括以下几个方面:1.跨平台性-JVM是Java语言“一次编写,到处运行”(WriteOnce,Ru</div>
                    </li>
                    <li><a href="/article/1773501994674225152.htm"
                           title="虚拟 DOM 的优缺点有哪些" target="_blank">虚拟 DOM 的优缺点有哪些</a>
                        <span class="text-muted">咕噜签名分发</span>
<a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/javascript/1.htm">javascript</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a>
                        <div>虚拟DOM(VirtualDOM)技术作为现代前端开发中的重要组成部分,已经成为了众多流行前端框架的核心特性。它的引入为前端开发带来了诸多优势,同时也需要我们认真思考其潜在的考量。下面简单的介绍一下虚拟DOM技术的优势与缺点,深入探讨其在实际应用中的影响。提升性能虚拟DOM的最大优势之一是提升页面性能。通过比较前后两次虚拟DOM树的差异,最小化实际DOM操作,从而减少页面重渲染时的性能消耗。这种优</div>
                    </li>
                    <li><a href="/article/1773495574226599936.htm"
                           title="3、JavaWeb-Ajax/Axios-前端工程化-Element" target="_blank">3、JavaWeb-Ajax/Axios-前端工程化-Element</a>
                        <span class="text-muted">所谓远行Misnearch</span>
<a class="tag" taget="_blank" href="/search/%23/1.htm">#</a><a class="tag" taget="_blank" href="/search/JavaWeb/1.htm">JavaWeb</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/ajax/1.htm">ajax</a><a class="tag" taget="_blank" href="/search/elementui/1.htm">elementui</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF%E6%A1%86%E6%9E%B6/1.htm">前端框架</a>
                        <div>P34Ajax介绍Ajax:AsynchroousJavaScriptAndXML,异步的JS和XMLJS网页动作,XML一种标记语言,存储数据,作用:数据交换:通过Ajax给服务器发送请求,并获取服务器响应的数据异步交互:在不重新加载整个页面的情况下,与服务器交换数据并实现更新部分网页的技术,例如:搜索联想、用户名是否可用的校验等等。同步与异步:同步:服务器在处理中客户端要处于等待状态,输入域名</div>
                    </li>
                    <li><a href="/article/1773495447948689408.htm"
                           title="docker怎么端口映射" target="_blank">docker怎么端口映射</a>
                        <span class="text-muted">Lance_mu</span>
<a class="tag" taget="_blank" href="/search/docker/1.htm">docker</a><a class="tag" taget="_blank" href="/search/%E5%AE%B9%E5%99%A8/1.htm">容器</a><a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a>
                        <div>1、默认固定的端口#Web服务器:WebApache或Nginx通常使用80端口HTTP:80HTTPS:443#数据库服务器MySQL:3306PostgreSQL:5432MongoDB:27017Redis:6379#邮件服务器SMTP:25POP3:110IMAP:143#其他服务SSH:22FTP:21DNS(域名解析):53代理服务器Squid:3128版本控制系统Git:9418(S</div>
                    </li>
                    <li><a href="/article/1773489909345091584.htm"
                           title="docker基础(一)" target="_blank">docker基础(一)</a>
                        <span class="text-muted">运维搬运工</span>
<a class="tag" taget="_blank" href="/search/%E5%AE%B9%E5%99%A8-docker/1.htm">容器-docker</a><a class="tag" taget="_blank" href="/search/docker/1.htm">docker</a><a class="tag" taget="_blank" href="/search/%E5%AE%B9%E5%99%A8/1.htm">容器</a><a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a>
                        <div>相关概念介绍Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖到一个可移植的容器中,然后发布到任何流行的linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,互相之间不会有任何接口。Docker有几个重要概念:dockerfile,配置文件,用来生成dockerimagedockerimage,交付部署的最小单元docker命令与API,定义命令与接口,支持第三方系统集</div>
                    </li>
                    <li><a href="/article/1773489025814953984.htm"
                           title="新注册的阿里云账号有哪些优惠?阿里云新用户必看优惠大合集" target="_blank">新注册的阿里云账号有哪些优惠?阿里云新用户必看优惠大合集</a>
                        <span class="text-muted">阿里云最新优惠和活动汇总</span>

                        <div>很多用户看到阿里云各种活动中的云服务器、云数据库、企业邮箱等云产品都仅限新用户购买之后,都纷纷直接注册了阿里云新账号之后购买,其实,阿里云新用户不仅可以优惠购买活动中的各种云产品,还有很多优惠,下面是“阿里云最新优惠和活动汇总”整理汇总的阿里云新用户必看优惠大合集。新注册的阿里云账号在购买活动中的云产品之前,还有免费领云产品通用代金券、抽取无门槛代金券、免费试用云服务器和正式购买云服务器等阿里云产</div>
                    </li>
                                <li><a href="/article/95.htm"
                                       title="PHP,安卓,UI,java,linux视频教程合集" target="_blank">PHP,安卓,UI,java,linux视频教程合集</a>
                                    <span class="text-muted">cocos2d-x小菜</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/UI/1.htm">UI</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a><a class="tag" taget="_blank" href="/search/PHP/1.htm">PHP</a><a class="tag" taget="_blank" href="/search/android/1.htm">android</a>
                                    <div>╔-----------------------------------╗┆                           </div>
                                </li>
                                <li><a href="/article/222.htm"
                                       title="zookeeper admin 笔记" target="_blank">zookeeper admin 笔记</a>
                                    <span class="text-muted">braveCS</span>
<a class="tag" taget="_blank" href="/search/zookeeper/1.htm">zookeeper</a>
                                    <div>  
Required Software 
1) JDK>=1.6 
2)推荐使用ensemble的ZooKeeper(至少3台),并run on separate machines 
3)在Yahoo!,zk配置在特定的RHEL boxes里,2个cpu,2G内存,80G硬盘 
   


数据和日志目录  
1)数据目录里的文件是zk节点的持久化备份,包括快照和事务日</div>
                                </li>
                                <li><a href="/article/349.htm"
                                       title="Spring配置多个连接池" target="_blank">Spring配置多个连接池</a>
                                    <span class="text-muted">easterfly</span>
<a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a>
                                    <div>项目中需要同时连接多个数据库的时候,如何才能在需要用到哪个数据库就连接哪个数据库呢? 
Spring中有关于dataSource的配置: 
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" 
  &nb</div>
                                </li>
                                <li><a href="/article/476.htm"
                                       title="Mysql" target="_blank">Mysql</a>
                                    <span class="text-muted">171815164</span>
<a class="tag" taget="_blank" href="/search/mysql/1.htm">mysql</a>
                                    <div>例如,你想myuser使用mypassword从任何主机连接到mysql服务器的话。 
 
GRANT ALL PRIVILEGES ON *.* TO 'myuser'@'%'IDENTIFIED BY 'mypassword' WI 
 
TH GRANT OPTION; 
 
如果你想允许用户myuser从ip为192.168.1.6的主机连接到mysql服务器,并使用mypassword作</div>
                                </li>
                                <li><a href="/article/603.htm"
                                       title="CommonDAO(公共/基础DAO)" target="_blank">CommonDAO(公共/基础DAO)</a>
                                    <span class="text-muted">g21121</span>
<a class="tag" taget="_blank" href="/search/DAO/1.htm">DAO</a>
                                    <div>        好久没有更新博客了,最近一段时间工作比较忙,所以请见谅,无论你是爱看呢还是爱看呢还是爱看呢,总之或许对你有些帮助。 
        DAO(Data Access Object)是一个数据访问(顾名思义就是与数据库打交道)接口,DAO一般在业</div>
                                </li>
                                <li><a href="/article/730.htm"
                                       title="直言有讳" target="_blank">直言有讳</a>
                                    <span class="text-muted">永夜-极光</span>
<a class="tag" taget="_blank" href="/search/%E6%84%9F%E6%82%9F/1.htm">感悟</a><a class="tag" taget="_blank" href="/search/%E9%9A%8F%E7%AC%94/1.htm">随笔</a>
                                    <div>  
1.转载地址:http://blog.csdn.net/jasonblog/article/details/10813313 
  
精华: 
“直言有讳”是阿里巴巴提倡的一种观念,而我在此之前并没有很深刻的认识。为什么呢?就好比是读书时候做阅读理解,我喜欢我自己的解读,并不喜欢老师给的意思。在这里也是。我自己坚持的原则是互相尊重,我觉得阿里巴巴很多价值观其实是基本的做人</div>
                                </li>
                                <li><a href="/article/857.htm"
                                       title="安装CentOS 7 和Win 7后,Win7 引导丢失" target="_blank">安装CentOS 7 和Win 7后,Win7 引导丢失</a>
                                    <span class="text-muted">随便小屋</span>
<a class="tag" taget="_blank" href="/search/centos/1.htm">centos</a>
                                    <div>一般安装双系统的顺序是先装Win7,然后在安装CentOS,这样CentOS可以引导WIN 7启动。但安装CentOS7后,却找不到Win7 的引导,稍微修改一点东西即可。 
一、首先具有root 的权限。 
     即进入Terminal后输入命令su,然后输入密码即可 
二、利用vim编辑器打开/boot/grub2/grub.cfg文件进行修改 
v</div>
                                </li>
                                <li><a href="/article/984.htm"
                                       title="Oracle备份与恢复案例" target="_blank">Oracle备份与恢复案例</a>
                                    <span class="text-muted">aijuans</span>
<a class="tag" taget="_blank" href="/search/oracle/1.htm">oracle</a>
                                    <div>Oracle备份与恢复案例 
一. 理解什么是数据库恢复当我们使用一个数据库时,总希望数据库的内容是可靠的、正确的,但由于计算机系统的故障(硬件故障、软件故障、网络故障、进程故障和系统故障)影响数据库系统的操作,影响数据库中数据的正确性,甚至破坏数据库,使数据库中全部或部分数据丢失。因此当发生上述故障后,希望能重构这个完整的数据库,该处理称为数据库恢复。恢复过程大致可以分为复原(Restore)与</div>
                                </li>
                                <li><a href="/article/1111.htm"
                                       title="JavaEE开源快速开发平台G4Studio v5.0发布" target="_blank">JavaEE开源快速开发平台G4Studio v5.0发布</a>
                                    <span class="text-muted">無為子</span>

                                    <div>  
我非常高兴地宣布,今天我们最新的JavaEE开源快速开发平台G4Studio_V5.0版本已经正式发布。 
  
访问G4Studio网站  
http://www.g4it.org       
2013-04-06 发布G4Studio_V5.0版本 
功能新增 
(1). 新增了调用Oracle存储过程返回游标,并将游标映射为Java List集合对象的标</div>
                                </li>
                                <li><a href="/article/1238.htm"
                                       title="Oracle显示根据高考分数模拟录取" target="_blank">Oracle显示根据高考分数模拟录取</a>
                                    <span class="text-muted">百合不是茶</span>
<a class="tag" taget="_blank" href="/search/PL%2FSQL%E7%BC%96%E7%A8%8B/1.htm">PL/SQL编程</a><a class="tag" taget="_blank" href="/search/oracle%E4%BE%8B%E5%AD%90/1.htm">oracle例子</a><a class="tag" taget="_blank" href="/search/%E6%A8%A1%E6%8B%9F%E9%AB%98%E8%80%83%E5%BD%95%E5%8F%96/1.htm">模拟高考录取</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0%E4%BA%A4%E6%B5%81/1.htm">学习交流</a>
                                    <div>题目要求: 
1,创建student表和result表
2,pl/sql对学生的成绩数据进行处理
3,处理的逻辑是根据每门专业课的最低分线和总分的最低分数线自动的将录取和落选 
  
  
1,创建student表,和result表 
学生信息表; 
create table student(
   student_id number primary key,--学生id</div>
                                </li>
                                <li><a href="/article/1365.htm"
                                       title="优秀的领导与差劲的领导" target="_blank">优秀的领导与差劲的领导</a>
                                    <span class="text-muted">bijian1013</span>
<a class="tag" taget="_blank" href="/search/%E9%A2%86%E5%AF%BC/1.htm">领导</a><a class="tag" taget="_blank" href="/search/%E7%AE%A1%E7%90%86/1.htm">管理</a><a class="tag" taget="_blank" href="/search/%E5%9B%A2%E9%98%9F/1.htm">团队</a>
                                    <div>责任 

  优秀的领导:优秀的领导总是对他所负责的项目担负起责任。如果项目不幸失败了,那么他知道该受责备的人是他自己,并且敢于承认错误。 
  
 差劲的领导:差劲的领导觉得这不是他的问题,因此他会想方设法证明是他的团队不行,或是将责任归咎于团队中他不喜欢的那几个成员身上。 
 
努力工作 

  优秀的领导:团队领导应该是团队成员的榜样。至少,他应该与团队中的其他成员一样努力工作。这仅仅因为他</div>
                                </li>
                                <li><a href="/article/1492.htm"
                                       title="js函数在浏览器下的兼容" target="_blank">js函数在浏览器下的兼容</a>
                                    <span class="text-muted">Bill_chen</span>
<a class="tag" taget="_blank" href="/search/jquery/1.htm">jquery</a><a class="tag" taget="_blank" href="/search/%E6%B5%8F%E8%A7%88%E5%99%A8/1.htm">浏览器</a><a class="tag" taget="_blank" href="/search/IE/1.htm">IE</a><a class="tag" taget="_blank" href="/search/DWR/1.htm">DWR</a><a class="tag" taget="_blank" href="/search/ext/1.htm">ext</a>
                                    <div>  做前端开发的工程师,少不了要用FF进行测试,纯js函数在不同浏览器下,名称也可能不同。对于IE6和FF,取得下一结点的函数就不尽相同: 
 
  IE6:node.nextSibling,对于FF是不能识别的; 
 
  FF:node.nextElementSibling,对于IE是不能识别的; 
 
兼容解决方式:var Div = node.nextSibl</div>
                                </li>
                                <li><a href="/article/1619.htm"
                                       title="【JVM四】老年代垃圾回收:吞吐量垃圾收集器(Throughput GC)" target="_blank">【JVM四】老年代垃圾回收:吞吐量垃圾收集器(Throughput GC)</a>
                                    <span class="text-muted">bit1129</span>
<a class="tag" taget="_blank" href="/search/%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6/1.htm">垃圾回收</a>
                                    <div>吞吐量与用户线程暂停时间 
  
衡量垃圾回收算法优劣的指标有两个: 
 
 吞吐量越高,则算法越好 
 暂停时间越短,则算法越好 
 
首先说明吞吐量和暂停时间的含义。 
  
垃圾回收时,JVM会启动几个特定的GC线程来完成垃圾回收的任务,这些GC线程与应用的用户线程产生竞争关系,共同竞争处理器资源以及CPU的执行时间。GC线程不会对用户带来的任何价值,因此,好的GC应该占</div>
                                </li>
                                <li><a href="/article/1746.htm"
                                       title="J2EE监听器和过滤器基础" target="_blank">J2EE监听器和过滤器基础</a>
                                    <span class="text-muted">白糖_</span>
<a class="tag" taget="_blank" href="/search/J2EE/1.htm">J2EE</a>
                                    <div> Servlet程序由Servlet,Filter和Listener组成,其中监听器用来监听Servlet容器上下文。 
监听器通常分三类:基于Servlet上下文的ServletContex监听,基于会话的HttpSession监听和基于请求的ServletRequest监听。 
  
 
 ServletContex监听器 
   ServletContex又叫application</div>
                                </li>
                                <li><a href="/article/1873.htm"
                                       title="博弈AngularJS讲义(16) - 提供者" target="_blank">博弈AngularJS讲义(16) - 提供者</a>
                                    <span class="text-muted">boyitech</span>
<a class="tag" taget="_blank" href="/search/js/1.htm">js</a><a class="tag" taget="_blank" href="/search/AngularJS/1.htm">AngularJS</a><a class="tag" taget="_blank" href="/search/api/1.htm">api</a><a class="tag" taget="_blank" href="/search/Angular/1.htm">Angular</a><a class="tag" taget="_blank" href="/search/Provider/1.htm">Provider</a>
                                    <div>  Angular框架提供了强大的依赖注入机制,这一切都是有注入器(injector)完成. 注入器会自动实例化服务组件和符合Angular API规则的特殊对象,例如控制器,指令,过滤器动画等。 
  那注入器怎么知道如何去创建这些特殊的对象呢? Angular提供了5种方式让注入器创建对象,其中最基础的方式就是提供者(provider), 其余四种方式(Value, Fac</div>
                                </li>
                                <li><a href="/article/2000.htm"
                                       title="java-写一函数f(a,b),它带有两个字符串参数并返回一串字符,该字符串只包含在两个串中都有的并按照在a中的顺序。" target="_blank">java-写一函数f(a,b),它带有两个字符串参数并返回一串字符,该字符串只包含在两个串中都有的并按照在a中的顺序。</a>
                                    <span class="text-muted">bylijinnan</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a>
                                    <div>

public class CommonSubSequence {

	/**
	 * 题目:写一函数f(a,b),它带有两个字符串参数并返回一串字符,该字符串只包含在两个串中都有的并按照在a中的顺序。
	 * 写一个版本算法复杂度O(N^2)和一个O(N) 。
	 * 
	 * O(N^2):对于a中的每个字符,遍历b中的每个字符,如果相同,则拷贝到新字符串中。
	 * O(</div>
                                </li>
                                <li><a href="/article/2127.htm"
                                       title="sqlserver 2000 无法验证产品密钥" target="_blank">sqlserver 2000 无法验证产品密钥</a>
                                    <span class="text-muted">Chen.H</span>
<a class="tag" taget="_blank" href="/search/sql/1.htm">sql</a><a class="tag" taget="_blank" href="/search/windows/1.htm">windows</a><a class="tag" taget="_blank" href="/search/SQL+Server/1.htm">SQL Server</a><a class="tag" taget="_blank" href="/search/Microsoft/1.htm">Microsoft</a>
                                    <div>在 Service Pack 4 (SP 4), 是运行 Microsoft Windows Server 2003、 Microsoft Windows Storage Server 2003 或 Microsoft Windows 2000 服务器上您尝试安装 Microsoft SQL Server 2000 通过卷许可协议 (VLA) 媒体。 这样做, 收到以下错误信息CD KEY的 SQ</div>
                                </li>
                                <li><a href="/article/2254.htm"
                                       title="[新概念武器]气象战争" target="_blank">[新概念武器]气象战争</a>
                                    <span class="text-muted">comsci</span>

                                    <div> 
 
       气象战争的发动者必须是拥有发射深空航天器能力的国家或者组织.... 
 
       原因如下: 
 
       地球上的气候变化和大气层中的云层涡旋场有密切的关系,而维持一个在大气层某个层次</div>
                                </li>
                                <li><a href="/article/2381.htm"
                                       title="oracle 中 rollup、cube、grouping 使用详解" target="_blank">oracle 中 rollup、cube、grouping 使用详解</a>
                                    <span class="text-muted">daizj</span>
<a class="tag" taget="_blank" href="/search/oracle/1.htm">oracle</a><a class="tag" taget="_blank" href="/search/grouping/1.htm">grouping</a><a class="tag" taget="_blank" href="/search/rollup/1.htm">rollup</a><a class="tag" taget="_blank" href="/search/cube/1.htm">cube</a>
                                    <div>oracle 中 rollup、cube、grouping 使用详解 -- 使用oracle 样例表演示 转自namesliu 
 
-- 使用oracle 的样列库,演示 rollup, cube, grouping 的用法与使用场景  
  
--- ROLLUP , 为了理解分组的成员数量,我增加了 分组的计数  COUNT(SAL)  
 </div>
                                </li>
                                <li><a href="/article/2508.htm"
                                       title="技术资料汇总分享" target="_blank">技术资料汇总分享</a>
                                    <span class="text-muted">Dead_knight</span>
<a class="tag" taget="_blank" href="/search/%E6%8A%80%E6%9C%AF%E8%B5%84%E6%96%99%E6%B1%87%E6%80%BB+%E5%88%86%E4%BA%AB/1.htm">技术资料汇总 分享</a>
                                    <div>本人汇总的技术资料,分享出来,希望对大家有用。 
 
http://pan.baidu.com/s/1jGr56uE 
 
资料主要包含: 
Workflow->工作流相关理论、框架(OSWorkflow、JBPM、Activiti、fireflow...) 
Security->java安全相关资料(SSL、SSO、SpringSecurity、Shiro、JAAS...) 
Ser</div>
                                </li>
                                <li><a href="/article/2635.htm"
                                       title="初一下学期难记忆单词背诵第一课" target="_blank">初一下学期难记忆单词背诵第一课</a>
                                    <span class="text-muted">dcj3sjt126com</span>
<a class="tag" taget="_blank" href="/search/english/1.htm">english</a><a class="tag" taget="_blank" href="/search/word/1.htm">word</a>
                                    <div>could 能够 
minute 分钟 
Tuesday 星期二 
February 二月 
eighteenth 第十八 
listen 听 
careful 小心的,仔细的 
short 短的 
heavy 重的 
empty 空的 
certainly 当然 
carry 携带;搬运 
tape 磁带 
basket 蓝子 
bottle 瓶 
juice 汁,果汁 
head 头;头部 
</div>
                                </li>
                                <li><a href="/article/2762.htm"
                                       title="截取视图的图片, 然后分享出去" target="_blank">截取视图的图片, 然后分享出去</a>
                                    <span class="text-muted">dcj3sjt126com</span>
<a class="tag" taget="_blank" href="/search/OS/1.htm">OS</a><a class="tag" taget="_blank" href="/search/Objective-C/1.htm">Objective-C</a>
                                    <div>OS 7 has a new method that allows you to draw a view hierarchy into the current graphics context. This can be used to get an UIImage very fast. 
I implemented a category method on UIView to get the vi</div>
                                </li>
                                <li><a href="/article/2889.htm"
                                       title="MySql重置密码" target="_blank">MySql重置密码</a>
                                    <span class="text-muted">fanxiaolong</span>
<a class="tag" taget="_blank" href="/search/MySql%E9%87%8D%E7%BD%AE%E5%AF%86%E7%A0%81/1.htm">MySql重置密码</a>
                                    <div>方法一: 
 在my.ini的[mysqld]字段加入: 
skip-grant-tables 
重启mysql服务,这时的mysql不需要密码即可登录数据库 
 然后进入mysql 
mysql>use mysql; 
 mysql>更新 user set password=password('新密码') WHERE User='root'; 
mysq</div>
                                </li>
                                <li><a href="/article/3016.htm"
                                       title="Ehcache(03)——Ehcache中储存缓存的方式" target="_blank">Ehcache(03)——Ehcache中储存缓存的方式</a>
                                    <span class="text-muted">234390216</span>
<a class="tag" taget="_blank" href="/search/ehcache/1.htm">ehcache</a><a class="tag" taget="_blank" href="/search/MemoryStore/1.htm">MemoryStore</a><a class="tag" taget="_blank" href="/search/DiskStore/1.htm">DiskStore</a><a class="tag" taget="_blank" href="/search/%E5%AD%98%E5%82%A8/1.htm">存储</a><a class="tag" taget="_blank" href="/search/%E9%A9%B1%E9%99%A4%E7%AD%96%E7%95%A5/1.htm">驱除策略</a>
                                    <div>Ehcache中储存缓存的方式 
  
目录 
1     堆内存(MemoryStore) 
1.1     指定可用内存 
1.2     驱除策略 
1.3     元素过期 
2   &nbs</div>
                                </li>
                                <li><a href="/article/3143.htm"
                                       title="spring mvc中的@propertysource" target="_blank">spring mvc中的@propertysource</a>
                                    <span class="text-muted">jackyrong</span>
<a class="tag" taget="_blank" href="/search/spring+mvc/1.htm">spring mvc</a>
                                    <div>  在spring mvc中,在配置文件中的东西,可以在java代码中通过注解进行读取了: 
 
@PropertySource  在spring 3.1中开始引入 
 
比如有配置文件 
config.properties 
 
mongodb.url=1.2.3.4 
mongodb.db=hello 
 
则代码中 
  

@PropertySource(&</div>
                                </li>
                                <li><a href="/article/3270.htm"
                                       title="重学单例模式" target="_blank">重学单例模式</a>
                                    <span class="text-muted">lanqiu17</span>
<a class="tag" taget="_blank" href="/search/%E5%8D%95%E4%BE%8B/1.htm">单例</a><a class="tag" taget="_blank" href="/search/Singleton/1.htm">Singleton</a><a class="tag" taget="_blank" href="/search/%E6%A8%A1%E5%BC%8F/1.htm">模式</a>
                                    <div>最近在重新学习设计模式,感觉对模式理解更加深刻。觉得有必要记下来。 
	第一个学的就是单例模式,单例模式估计是最好理解的模式了。它的作用就是防止外部创建实例,保证只有一个实例。
	单例模式的常用实现方式有两种,就人们熟知的饱汉式与饥汉式,具体就不多说了。这里说下其他的实现方式
	静态内部类方式: 
package test.pattern.singleton.statics;

publ</div>
                                </li>
                                <li><a href="/article/3397.htm"
                                       title=".NET开源核心运行时,且行且珍惜" target="_blank">.NET开源核心运行时,且行且珍惜</a>
                                    <span class="text-muted">netcome</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/.net/1.htm">.net</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E6%BA%90/1.htm">开源</a>
                                    <div>背景 
2014年11月12日,ASP.NET之父、微软云计算与企业级产品工程部执行副总裁Scott Guthrie,在Connect全球开发者在线会议上宣布,微软将开源全部.NET核心运行时,并将.NET 扩展为可在 Linux 和 Mac OS 平台上运行。.NET核心运行时将基于MIT开源许可协议发布,其中将包括执行.NET代码所需的一切项目——CLR、JIT编译器、垃圾收集器(GC)和核心</div>
                                </li>
                                <li><a href="/article/3524.htm"
                                       title="使用oscahe缓存技术减少与数据库的频繁交互" target="_blank">使用oscahe缓存技术减少与数据库的频繁交互</a>
                                    <span class="text-muted">Everyday都不同</span>
<a class="tag" taget="_blank" href="/search/Web/1.htm">Web</a><a class="tag" taget="_blank" href="/search/%E9%AB%98%E5%B9%B6%E5%8F%91/1.htm">高并发</a><a class="tag" taget="_blank" href="/search/oscahe%E7%BC%93%E5%AD%98/1.htm">oscahe缓存</a>
                                    <div>此前一直不知道缓存的具体实现,只知道是把数据存储在内存中,以便下次直接从内存中读取。对于缓存的使用也没有概念,觉得缓存技术是一个比较”神秘陌生“的领域。但最近要用到缓存技术,发现还是很有必要一探究竟的。 
  
缓存技术使用背景:一般来说,对于web项目,如果我们要什么数据直接jdbc查库好了,但是在遇到高并发的情形下,不可能每一次都是去查数据库,因为这样在高并发的情形下显得不太合理——</div>
                                </li>
                                <li><a href="/article/3651.htm"
                                       title="Spring+Mybatis 手动控制事务" target="_blank">Spring+Mybatis 手动控制事务</a>
                                    <span class="text-muted">toknowme</span>
<a class="tag" taget="_blank" href="/search/mybatis/1.htm">mybatis</a>
                                    <div>@Override 
   public boolean testDelete(String jobCode) throws Exception { 
      boolean flag = false; 
 &nbs</div>
                                </li>
                                <li><a href="/article/3778.htm"
                                       title="菜鸟级的android程序员面试时候需要掌握的知识点" target="_blank">菜鸟级的android程序员面试时候需要掌握的知识点</a>
                                    <span class="text-muted">xp9802</span>
<a class="tag" taget="_blank" href="/search/android/1.htm">android</a>
                                    <div>熟悉Android开发架构和API调用 
掌握APP适应不同型号手机屏幕开发技巧 
熟悉Android下的数据存储  
熟练Android Debug Bridge Tool 
熟练Eclipse/ADT及相关工具  
熟悉Android框架原理及Activity生命周期 
熟练进行Android UI布局 
熟练使用SQLite数据库; 
熟悉Android下网络通信机制,S</div>
                                </li>
                </ul>
            </div>
        </div>
    </div>

<div>
    <div class="container">
        <div class="indexes">
            <strong>按字母分类:</strong>
            <a href="/tags/A/1.htm" target="_blank">A</a><a href="/tags/B/1.htm" target="_blank">B</a><a href="/tags/C/1.htm" target="_blank">C</a><a
                href="/tags/D/1.htm" target="_blank">D</a><a href="/tags/E/1.htm" target="_blank">E</a><a href="/tags/F/1.htm" target="_blank">F</a><a
                href="/tags/G/1.htm" target="_blank">G</a><a href="/tags/H/1.htm" target="_blank">H</a><a href="/tags/I/1.htm" target="_blank">I</a><a
                href="/tags/J/1.htm" target="_blank">J</a><a href="/tags/K/1.htm" target="_blank">K</a><a href="/tags/L/1.htm" target="_blank">L</a><a
                href="/tags/M/1.htm" target="_blank">M</a><a href="/tags/N/1.htm" target="_blank">N</a><a href="/tags/O/1.htm" target="_blank">O</a><a
                href="/tags/P/1.htm" target="_blank">P</a><a href="/tags/Q/1.htm" target="_blank">Q</a><a href="/tags/R/1.htm" target="_blank">R</a><a
                href="/tags/S/1.htm" target="_blank">S</a><a href="/tags/T/1.htm" target="_blank">T</a><a href="/tags/U/1.htm" target="_blank">U</a><a
                href="/tags/V/1.htm" target="_blank">V</a><a href="/tags/W/1.htm" target="_blank">W</a><a href="/tags/X/1.htm" target="_blank">X</a><a
                href="/tags/Y/1.htm" target="_blank">Y</a><a href="/tags/Z/1.htm" target="_blank">Z</a><a href="/tags/0/1.htm" target="_blank">其他</a>
        </div>
    </div>
</div>
<footer id="footer" class="mb30 mt30">
    <div class="container">
        <div class="footBglm">
            <a target="_blank" href="/">首页</a> -
            <a target="_blank" href="/custom/about.htm">关于我们</a> -
            <a target="_blank" href="/search/Java/1.htm">站内搜索</a> -
            <a target="_blank" href="/sitemap.txt">Sitemap</a> -
            <a target="_blank" href="/custom/delete.htm">侵权投诉</a>
        </div>
        <div class="copyright">版权所有 IT知识库 CopyRight © 2000-2050 E-COM-NET.COM , All Rights Reserved.
<!--            <a href="https://beian.miit.gov.cn/" rel="nofollow" target="_blank">京ICP备09083238号</a><br>-->
        </div>
    </div>
</footer>
<!-- 代码高亮 -->
<script type="text/javascript" src="/static/syntaxhighlighter/scripts/shCore.js"></script>
<script type="text/javascript" src="/static/syntaxhighlighter/scripts/shLegacy.js"></script>
<script type="text/javascript" src="/static/syntaxhighlighter/scripts/shAutoloader.js"></script>
<link type="text/css" rel="stylesheet" href="/static/syntaxhighlighter/styles/shCoreDefault.css"/>
<script type="text/javascript" src="/static/syntaxhighlighter/src/my_start_1.js"></script>





</body>

</html>