前些日子研究了一下nginx,也基于它的源码编写了一些程序,但是发现这种“原始”的做法即使是一个简单的HelloWorld程序就非常的耗费时间。后来发现了openresty这个东西,它是前人集成了nginx和lua的,nginx的高阶版本。lua是一种小巧的,高级的脚本语言,能够很方便地在nginx的配置文件中编写出自己的业务流程。
业务说明:
传统的权限控制,如果是J2EE,都会在spring中添加filter的管控,这在只有一台服务器里面,并没有什么问题,但是在集群的世界里,这显然不怎么合理。我们不希望我们的上游服务器来处理权限的问题,而是在权限信息到达之前就已经处理好了,上游服务器只要跑数据,处理业务就行。于是权限控制这一功能模块,就放在负责分发任务的nginx身上,如果你是用nginx来搭建集群的话。。。
准备:
操作系统:centos,ubuntu感觉不怎么好用,因为动不动就会提示容量不足,本人也是不信邪,一次又一次的重装ubuntu,后来干脆换centos。
功能软件,如下图,这是我的虚拟机上的版本。
1、openresty-1.11.2.5 安装方法参照 https://openresty.org/cn/ ,安装完成后,就已经是nginx+lua了。最好是下载源码版,,然后自己编译一下,还是很爽的。
2、Redis-3.2.10 下载地址 https://redis.io/ 解压压缩包,然后打开解压后的目录,编译安装(网上很多教程)
3、lua-resty-http-0.11 这是个开源的第三方包,用于处理http的,就是访问地址用的,下载地址是 https://github.com/pintsized/lua-resty-http/ 虽然openresty本身也有,但是亲测之后并不好用
注意上面都是一堆源码,真正安装后可能不是在这个路径下了
前两个的安装过程相对独立,没什么好说的,找找资料就可以,关键说一下lua-rety-http的集成过程,打开文件夹找到下面两个文件,拷贝这两个文件
然后去到openresty安装完成后的地址,粘贴到这个文件夹下,准备工作到这里就结束了
openresty实际上也是nginx,我们依然可以在openresty的安装目录下,找到nginx的文件夹,这部分是独立,可以完全可以当作一般nginx那样启动,然后是代码。
先启动 redis
[plain] view plain copy
1. [root@localhost sbin]# ./redis-server /home/sword/Downloads/redis-3.2.10/redis.conf
然后修改nginx.conf
[cpp] view plain copy
1. #user nobody;
2. worker_processes 1;
3.
4.
5. #error_log logs/error.log;
6. #error_log logs/error.log notice;
7. #error_log logs/error.log info;
8. #pid logs/nginx.pid;
9. events {
10. worker_connections 1024;
11. }
12. http {
13. include mime.types;
14. default_type text/html;
15. "/usr/local/openresty/lualib/?.lua;;"; #使resty.http生效
16. "/usr/local/openresty/lualib/?.so;;";
17. #log_format main '$remote_addr - $remote_user [$time_local] "$request" '
18. # '$status $body_bytes_sent "$http_referer" '
19. # '"$http_user_agent" "$http_x_forwarded_for"';
20. #access_log logs/access.log main;
21. upstream swordnet.com{
22. server 132.121.164.203:8280;
23. }
24. sendfile on;
25. #tcp_nopush on;
26. #keepalive_timeout 0;
27. keepalive_timeout 65;
28. #gzip on;
29. server {
30. listen 80;
31. server_name localhost;
32. charset utf-8;
33. #access_log logs/host.access.log main;
34. location ~ .*/(token/[^/|\?]*).*{#(1)、在客户端输入的url,只要是符合 http://localhost/xxx/token/xxx的都会在这里被捕获
35. set $token $1;#(2)、识别(1)中的正则表达式,取出()中的内容,并赋值给$token
36. content_by_lua_block {
37. local http = require "resty.http";#导入resty.http和resty.redis包
38. local redis = require "resty.redis";
39. local httpc = http.new();
40. local instance = redis.new();
41. local var = ngx.var;#使用nginx自带的变量池
42. local token = var.token;#使用(2)中的$token 这里是token/swordnet123
43. local ok,err = instance:connect("127.0.0.1","6379");#连接redis
44. if not ok then
45. ngx.print("error!!!");
46. end
47. instance:set("token/swordnet123","http://127.0.0.1:81/xxx/zzz/showData?entityid=4406041007625");#往redis中添加测试数据
48. instance:set("wto78425@$12Gz",1);
49. local urlc = instance:get(token);#(3)、取出 http://127.0.0.1:81/xxx/zzz/showData?entityid=4406041007625,观察这个连接的域,依然是nginx的ip和port
50. if urlc == ngx.null then
51. ngx.print("error");
52. else
53. local res, err = httpc:request_uri(urlc,{ method = "GET",});#发出新的请求
54. ngx.print(res.body);
55. end;
56. }
57. }
58. }
59. server {
60. listen 81;
61. server_name localhost;
62. charset utf-8;
63. #access_log logs/host.access.log main;
64. location /xxx {(3)中发出的新请求会在这里被捕获
65. proxy_pass http://swordnet.com;
66. }
67.
68.
69. }
70.
71. # another virtual host using mix of IP-, name-, and port-based configuration
72. #
73. #server {
74. # listen 8000;
75. # listen somename:8080;
76. # server_name somename alias another.alias;
77.
78.
79. # location / {
80. # root html;
81. # index index.html index.htm;
82. # }
83. #}
84.
85.
86.
87.
88. # HTTPS server
89. #
90. #server {
91. # listen 443 ssl;
92. # server_name localhost;
93.
94.
95. # ssl_certificate cert.pem;
96. # ssl_certificate_key cert.key;
97.
98.
99. # ssl_session_cache shared:SSL:1m;
100. # ssl_session_timeout 5m;
101.
102.
103. # ssl_ciphers HIGH:!aNULL:!MD5;
104. # ssl_prefer_server_ciphers on;
105.
106.
107. # location / {
108. # root html;
109. # index index.html index.htm;
110. # }
111. #}
112.
113.
114. }
最后启动nginx,在浏览器虽然输入个什么http://localhost/tt/token/swordnet123测试一下结果。