目录
一、nginx分发层到应用层
通过调用本身的
nginx
的
hash
分发模块分发到应用层并且实现动态负载均衡,并且在应用层当中调用
php-fpm
1、目录结构如下
2、分发层配置文件
2.1)简单配置并验证
2.2)动态负载均衡配置
- 分发层配置文件
- 搭建consul容器
#拉取consul镜像
docker pull consul
#启动容器consul服务
docker run -d -p 8700:8500 -h node1 --name node1 consul agent -server -bootstrap-expect=1 -node=node1 -client 0.0.0.0 -ui
#如果非容器consul启动使用以下命令
consul agent -server -bootstrap-expect 1 -data-dir /tmp/consul -node=ali_1 -bind=172.27.0.8 -ui -client 0.0.0.0
#启动consul服务
curl -X PUT -d '{"weight":1,"max_fails":2,"fail_timeout":10}' http://127.0.0.1:8700/v1/kv/upstreams/servers/外网IP地址:映射端口
二、lua连接redis集群
1、下载redis集群包
redis集群包地址 https://github.com/steve0511/resty-redis-cluster
2、源码目录通过make生成.so文件,通过lua_package_cpath加载.so文件 (我的下载的文件放在/docker/cache/project/code/nginx/application/common目录下)
3、定时获取集群信息,动态获取集群地址
通过在进程启动的时候定时获取
redis
连接地址
,
在使用时获取内存内的
redis
集群地址
curl -X PUT -d 'redis集群外网访问ip地址:redis集群外网映射端口' http://127.0.0.1:8700/v1/kv/redis-cluster-1/
如果配置路径没问题,(由于暂时还没有任何文件)浏览器访问结果如下:
三、使用OpenResty 组件管理工具
很多开发语言
/
环境都会提供配套的包管理工具,例如
npm/Node.js
、
cpan/Perl
、
gem/Ruby
等,它们可以方便地安装功能组件,辅助用户的开发工作,节约用户的时间和经理。OpenResty
也有功能类似的工具,名叫
opm
。
OpenResty
维护一个官方组件库(
opm.openresty.org
)
,opm
就是库的客户端,可以把组件库里的组件下载到本地,并管理本地的组件列表。
opm
的用法很简单,常用的命令有:
search:以关键字搜索关键的组件。
get:安装功能组件(注意不是 install)。
info:显示已安装组件的详细信息。
list:列出所有本地已经安装的组件。
upgrad:更新某个已安装组件。
update:更新所有已安装组件。
remove:移除某个已安装组件。
opm 默认的操作目录是 “/usr/local/openresty/site”,但是也可以在命令行参数 “--install-dir=PATH” 安装到其他目录,或者用参数 “–cwd” 安装到当前目录的 "./resty_module/" 目录里。
注意:要使用opm我们的环境当中还缺少一个依赖 yum install perl-Digest-MD5 -y
容器应用层里安装
安装lua_resty_consul 工具包
https://github.com/hamishforbes/lua-resty-consul
#在应用层首先安装依赖包
yum install perl-Digest-MD5 -y
#将hamishforbes/lua-resty-consul安装到/usr/local/openresty/lualib/project/common下
opm --install-dir=/usr/local/openresty/lualib/project/common get hamishforbes/lua-resty-consul
应用层nginx.conf
user root;
worker_processes 2;
daemon off;#避免nginx在后台运行
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 20480;#单个进程允许的客户端最大连接数
}
http {
include mime.types;
#default_type application/octet-stream;
lua_code_cache off; #关闭代码缓存上线后去掉
#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 logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
gzip on;
lua_package_path "/usr/local/openresty/lualib/project/common/lualib/?.lua;;/usr/local/openresty/lualib/project/common/resty-redis-cluster/lib/?.lua;;";
lua_package_cpath "/usr/local/openresty/lualib/project/common/resty-redis-cluster/src/?.so;;";
lua_shared_dict redis_cluster_slot_locks 100k;
lua_shared_dict redis_cluster_addr 20k;
init_worker_by_lua_file /usr/local/openresty/lualib/project/init.lua;
server {
listen 80;
location / {
#root /var/www/html;
content_by_lua_file /usr/local/openresty/lualib/project/application.lua;
#index index.php index.html index.htm;
#autoindex on;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
location ~ \.php/?.* {
root /var/www/html;#php-fpm容器中的路径,不是nginx路径
fastcgi_pass 114.67.105.89:9002;#对应容器的端口
fastcgi_index index.php;
#为php-fpm指定的根目录
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; #加了这一项
#定义变量$path_info,存放pathinfo信息
set $path_info "";
if ($fastcgi_script_name ~ "^(.+?\.php)(/.+)$") {
#将文件地址赋值给变量 $real_script_name
set $real_script_name $1;
#将文件地址后的参数赋值给变量 $path_info
set $path_info $2;
}
#配置fastcgi的一些参数
fastcgi_param SCRIPT_NAME $real_script_name;
fastcgi_param PATH_INFO $path_info;
include /usr/local/openresty/nginx/conf/fastcgi_params;
}
}
}
application.lua文件
local redis_list = {}
local ngx_re_split = require("ngx.re").split
local ip_addr = ngx.shared.redis_cluster_addr:get("redis_addr")
local ip_addr_table = ngx_re_split(ip_addr,",")
for key,value in ipairs(ip_addr_table) do
local ip_addr = ngx_re_split(value,":")
redis_list[key] = {ip=ip_addr[1],port=ip_addr[2]}
-- ngx.print(value)
end
local config = {
name = "testCluster", --rediscluster name
serv_list = redis_list,
keepalive_timeout = 60000, --redis connection pool idle timeout
keepalive_cons = 1000, --redis connection pool size
connection_timout = 1000, --timeout while connecting
max_redirection = 5, --maximum retry attempts for redirection,
auth = "binleen" --set password while setting auth
}
local redis_cluster = require "rediscluster"
local red_c = redis_cluster:new(config)
local v, err = red_c:get("name")
if err then
ngx.log(ngx.ERR, "err: ", err)
else
ngx.say(v)
end
init.lua文件
--启动器当中获取redis集群表
local delay = 5
local handler
handler = function (premature)
local resty_consul = require('resty.consul')
local consul = resty_consul:new({
host = "114.67.105.89",
port = 8700,
connect_timeout = (60*1000), -- 60s
read_timeout = (60*1000), -- 60s
})
local res, err = consul:list_keys("redis-cluster") -- Get all keys
if not res then
ngx.log(ngx.ERR, err)
return
end
local keys = {}
if res.status == 200 then
keys = res.body
end
local ip_addr = ''
for key,value in ipairs(keys) do
local res, err = consul:get_key(value)
if not res then
ngx.log(ngx.ERR, err)
return
end
if table.getn(keys) == key then
ip_addr = ip_addr..res.body[1].Value
else
ip_addr = ip_addr..res.body[1].Value..","
end
ngx.shared.redis_cluster_addr:set("redis_addr",ip_addr)
end
end
if( 0 == ngx.worker.id() ) then
--第一次立即执行 ngx.timer.at:只执行一次
local ok, err = ngx.timer.at(0, handler)
if not ok then
ngx.log(ngx.ERR, "第一次执行错误: ", err)
return
end
--第二次定时执行
local ok, err = ngx.timer.every(delay, handler)
if not ok then
ngx.log(ngx.ERR, "定时执行错误: ", err)
return
end
end