创建并挂载容器
先准备挂载的目录,由于直接挂载目录会导致目录里面文件全部丢失,所以先创建容器,将其中的文件先复制出来,然后删除容器,在重新启动容器并挂载
创建容器
docker run --name nginx -p 9001:80 -d nginx
创建文件夹
# 创建挂载目录
mkdir -p /home/nginx/conf
mkdir -p /home/nginx/log
mkdir -p /home/nginx/html
复制容器中文件到虚拟机
# 将容器nginx.conf文件复制到宿主机
docker cp nginx:/etc/nginx/nginx.conf /home/nginx/conf/nginx.conf
# 将容器conf.d文件夹下内容复制到宿主机
docker cp nginx:/etc/nginx/conf.d /home/nginx/conf/conf.d
# 将容器中的html文件夹复制到宿主机
docker cp nginx:/usr/share/nginx/html /home/nginx/
查看文件
删除容器
创建并挂载
docker run \
-p 9002:80 \
--name nginx \
-v /home/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \
-v /home/nginx/conf/conf.d:/etc/nginx/conf.d \
-v /home/nginx/log:/var/log/nginx \
-v /home/nginx/html:/usr/share/nginx/html \
-d nginx:latest
测试容器
location匹配说明
这个location的值是匹配请求连接中的uri
语法格式: location [= | ~ | ~* | ^~] uri { ... }
a)uri表示待匹配的请求字符,可以是正则或者不是正则字符例如:vison.action 表示标准uri ; \.action$表示以action结尾url
b) “[]”中括号中的是可选项,用来改变请求字符串和uri的匹配方式,
这里有四种:
“=” 用于标准的uri(没有使用正则表达式等)前,要求请求字符串和uri严格匹配,如果匹配成功就停止搜索并立即处理请求
“~” 用于表示uri包含正则表达式,并且区分大小写
“~*”,用于表示uri包含正则表达式,并且不区分大小写 ,
注意:如果包含uri正则表达式,必须使用“~” 或者 “~*” 标识
“^~” ,用于标准uri(没有使用正则表达式),要求Nginx服务器找到表示uri和请求字符串匹配度最高的location后,立即使用location处理请求,而不使用location块中的正则uri和请求字符串做匹配。
注意点:浏览器在传送uri的时候会对部分字符url编码,例如空格编码为“%20”,问好编码为“%3f”等,“^~”它可以对这些符号进行编码处理。例如如果URI为“/html/%20/data”,则当Nginx可以收到配置“^~ /html/ /data” 同样也是匹配成功的。
负载均衡
介绍
跨多个应用程序实例的负载平衡是优化资源利用率、最大化吞吐量、减少延迟和确保容错配置的常用技术。
使用nginx作为一个非常高效的HTTP负载均衡器,可以将流量分配到多个应用服务器,并通过nginx提高web应用程序的性能、可扩展性和可靠性。
负载平衡方法
nginx支持以下负载平衡机制(或方法):
- 循环-对应用服务器的请求以循环方式分布,
- 最少连接-下一个请求被分配给具有最少活动连接数的服务器,
- ip散列——散列函数用于确定下一个请求应该选择哪个服务器(基于客户端的ip地址)。
默认的负载均衡配置
http {
upstream myapp1 {
server srv1.example.com;
server srv2.example.com;
server srv3.example.com;
}
server {
listen 80;
location / {
proxy_pass http://myapp1;
}
}
}
在上面的示例中,同一应用程序有3个实例在srv1-srv3上运行。如果没有专门配置负载平衡方法,则默认为循环。所有请求都被代理到服务器组myapp1,nginx应用HTTP负载平衡来分发请求。
连接最少的负载平衡
另一个负载平衡规程是最不相关的。最少连接允许在某些请求需要更长时间才能完成的情况下更公平地控制应用程序实例的负载。
在连接最少的负载平衡下,nginx将尽量不让繁忙的应用程序服务器过载过多的请求,而是将新的请求分发到不那么繁忙的服务器。
当使用Least_conn指令作为服务器组配置的一部分时,nginx中的最小连接负载平衡被激活:
upstream myapp1 {
least_conn;
server srv1.example.com;
server srv2.example.com;
server srv3.example.com;
}
ip哈希负载平衡
请注意,通过循环或连接最少的负载平衡,每个后续客户端的请求都可能被分发到不同的服务器。无法保证同一客户端将始终指向同一服务器。
如果需要将客户端绑定到特定的应用程序服务器——换句话说,就总是尝试选择特定的服务器而言,使客户端的会话“粘性”或“持久性”——那么可以使用ip哈希负载平衡机制。
使用ip散列,客户端的ip地址被用作散列密钥,以确定应该为客户端的请求选择服务器组中的哪个服务器。此方法可确保来自同一客户端的请求始终指向同一服务器,除非该服务器不可用。
要配置ip哈希负载平衡,只需将ip_hash指令添加到服务器(上游)组配置中:
upstream myapp1 {
ip_hash;
server srv1.example.com;
server srv2.example.com;
server srv3.example.com;
}
加权负载平衡
还可以通过使用服务器权重来进一步影响nginx负载平衡算法。
在上面的示例中,没有配置服务器权重,这意味着所有指定的服务器都被视为对特定负载平衡方法具有同等资格。
特别是循环,它还意味着在服务器之间或多或少平等地分配请求——前提是有足够的请求,并且当请求以统一的方式处理并足够快地完成时。
当为服务器指定权重参数时,权重将作为负载平衡决策的一部分。
upstream myapp1 {
server srv1.example.com weight=3;
server srv2.example.com;
server srv3.example.com;
}
使用此配置,每5个新请求将分布在应用程序实例中,如下所示:3个请求将定向到srv1,一个请求将转到srv2,另一个请求--到srv3。
在最近版本的nginx中,同样可以使用连接最少的权重和ip哈希负载平衡。
使用ip作为host
动态代理(主要修改http段)
复制一个配置文件,直接复制conf.d下面的default.conf文件为test.conf
加上配置
[root@localhost conf.d]# cat test.conf
server {
listen 80;
server_name localhost;
location ~ /test1/ {
proxy_pass http://10.21.36.85:8001;
}
location ~ /test2/ {
proxy_pass http://10.21.36.85:8002;
}
}
创建两个相同服务,端口分别为8001和8002,借口如下
浏览器访问
这边就实现了动态代理,当url中包含test1时就访问8001服务,包含test2时就访问8002端口
多server代理
删除老容器,因为老容器只暴露了一个80端口,现在创建新容器,暴露8001和8002端口
docker run --name nginx -d -p 8001:8001 -p 8002:8002 -v /home/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \
> -v /home/nginx/conf/conf.d:/etc/nginx/conf.d \
> -v /home/nginx/log:/var/log/nginx \
> -v /home/nginx/html:/usr/share/nginx/html \
> nginx
修改配置如下
server {
listen 8001;
server_name localhost;
location ~ /test2/ {
proxy_pass http://10.21.36.85:8001;
}
}
server {
listen 8002;
server_name localhost;
location ~ /test2/ {
proxy_pass http://10.21.36.85:8002;
}
}
当端口是8001时访问8001服务,当端口是8002时访问8002服务
替换url中的值
nginx地址http://192.168.31.128
配置文件如下 这边访问地址是http://192.168.31.128:8001/api/test 下面的配置会替换api为test1并转发到如下地址
server {
listen 8001;
server_name localhost;
location /api/ {
rewrite ^/api(.*)$ /test1$1 break;
proxy_pass http://10.21.36.85:8001;
}
}
上面是替换开头的api为test,下面的是替换最后的api为test
server {
listen 8001;
server_name localhost;
location / {
rewrite ^/(.*)/api(.*)$ /$1/test$2 break;
proxy_pass http://10.21.36.85:8001;
}
}
总结一下替换规则
替换表达式中 / 就表示url的 / ,(.*)表示通配符,可以表示n个字母或数字 ,^表示开始,$表示结束
后面的$1就对应前面表达式中的第一个(.*),$2表示第二个(.*),以此类推
举个例子
请求路径是 xxxx/xxxx/xxxx/xxxx ,
现在要把第一个xxxx中的前两个xx替换为yy ,只需要如下表达式即可
rewrite ^/xx(.*)/(.*)/(.*)/(.*) /yy$1/$2/$3/$4
现在要把第一个xxxx中的xxxx替换为yy ,只需要如下表达式即可
rewrite ^/xxxx/(.*)/(.*)/(.*) /yy/$2/$3/$4
现在要把第二个xxxx中的xxxx替换为yy ,只需要如下表达式即可
rewrite ^/(.*)/xxxx/(.*)/(.*) /yy$1/$2/$3/$4
以此类推