tengine源代码分析(一)-- 组件分析与编译运行

tengine代码树里的ngx_http_lua_module就是openresty的lua-nginx-module

看它的readme:https://github.com/alibaba/tengine/blob/master/modules/ngx_http_lua_module/README.markdown

资料收集

简单的说,lua跟python差不多。

看这个中文文档快速入门:https://www.runoob.com/lua/lua-tutorial.html

LUA与LuaJIR:https://blog.csdn.net/qq_41489540/article/details/117844285

reactor与proactor,据说tengine的lua是proactor的: https://www.cnblogs.com/chenssy/p/15526729.html

 

ngx_http_lua_module: https://github.com/openresty/lua-nginx-module#readme

ngx_devel_kit: https://github.com/vision5/ngx_devel_kit

 

 代码

ngx_http_lua依赖: ngx_devel_kit, LuaJIT

入口:

~/Source/tengine-tengine-3.1.0/modules/ngx_http_lua_module/src/ngx_http_lua_module.c

 配置文件中的lua代码

ingress给tengine设置的配置文件,可以看见其中多处使用了lua

  1 # Configuration checksum: 18225032199610257382
  2 
  3 # setup custom paths that do not require root access
  4 pid /tmp/nginx.pid;
  5 
  6 user root;
  7 
  8 load_module /etc/nginx/modules/ngx_http_geoip_module.so;
  9 
 10 daemon off;
 11 
 12 worker_processes 2;
 13 
 14 worker_rlimit_nofile 523264;
 15 
 16 worker_shutdown_timeout 240s ;
 17 
 18 events {
 19     multi_accept on;
 20     worker_connections 16384;
 21     accept_mutex on;
 22     use epoll;
 23 }
 24 
 25 include /etc/nginx/apps/proc.conf;
 26 
 27 http {
 28     lua_package_path "/etc/nginx/lua/?.lua;;";
 29 
 30     lua_shared_dict csp_data 10m;
 31     lua_shared_dict deny_lock 1m;
 32     lua_shared_dict deny_data 1000m;
 33 
 34     lua_use_default_type off;
 35 
 36     lua_shared_dict balancer_ewma 10M;
 37     lua_shared_dict balancer_ewma_last_touched_at 10M;
 38     lua_shared_dict balancer_ewma_locks 1M;
 39     lua_shared_dict certificate_data 20M;
 40     lua_shared_dict certificate_servers 5M;
 41     lua_shared_dict configuration_data 20M;
 42 
 43     init_by_lua_block {
 44         collectgarbage("collect")
 45 
 46         -- init modules
 47         local ok, res
 48 
 49         ok, res = pcall(require, "lua_ingress")
 50         if not ok then
 51         error("require failed: " .. tostring(res))
 52         else
 53         lua_ingress = res
 54         lua_ingress.set_config( {
 55             use_forwarded_headers = false,
 56             use_proxy_protocol = false,
 57             is_ssl_passthrough_enabled = false,
 58             http_redirect_code = 308,
 59             listen_ports = {
 60                 ssl_proxy = "442", https = "443"
 61             }
 62             ,
 63 
 64             hsts = true,
 65             hsts_max_age = 15724800,
 66             hsts_include_subdomains = true,
 67             hsts_preload = false,
 68         }
 69         )
 70         end
 71 
 72         ok, res = pcall(require, "configuration")
 73         if not ok then
 74         error("require failed: " .. tostring(res))
 75         else
 76         configuration = res
 77         end
 78 
 79         ok, res = pcall(require, "balancer")
 80         if not ok then
 81         error("require failed: " .. tostring(res))
 82         else
 83         balancer = res
 84         end
 85 
 86         ok, res = pcall(require, "monitor")
 87         if not ok then
 88         error("require failed: " .. tostring(res))
 89         else
 90         monitor = res
 91         end
 92 
 93         ok, res = pcall(require, "certificate")
 94         if not ok then
 95         error("require failed: " .. tostring(res))
 96         else
 97         certificate = res
 98         end
 99 
100         ok, res = pcall(require, "plugins")
101         if not ok then
102         error("require failed: " .. tostring(res))
103         else
104         plugins = res
105         end
106         -- load all plugins that'll be used here
107         plugins.init( {
108         }
109         )
110     }
111 
112     init_worker_by_lua_block {
113         lua_ingress.init_worker()
114         balancer.init_worker()
115 
116         monitor.init_worker()
117 
118         plugins.run()
119     }
120 
121     geo $dontlog {
122         default 0;
123         127.0.0.1/32 1;
124         192.168.0.0/16 1;
125         121.0.29.226/32 1;
126     }
127     geo $nolog {
128         default 0;
129     }
130     geo $no_reqstatus {
131         default 0;
132     }
133     geo $x_connection {
134         default "";
135     }
136 
137     # start hot reload config
138     ingress_gateway_hash_num shm_service_cfg 500000;
139     ingress_gateway_pool_size shm_service_cfg 256m;
140     ingress_gateway_update_interval shm_service_cfg 10s;
141     ingress_gateway_shm_config shm_service_cfg ShmServiceCfg 256m /etc/nginx/shm_service_cfg.lock;
142 
143     geoip_country /etc/nginx/geoip/GeoIP.dat;
144     geoip_city /etc/nginx/geoip/GeoLiteCity.dat;
145     geoip_org /etc/nginx/geoip/GeoIPASNum.dat;
146     geoip_proxy_recursive on;
147 
148     aio threads;
149     aio_write on;
150 
151     tcp_nopush on;
152     tcp_nodelay on;
153 
154     log_subrequest on;
155 
156     reset_timedout_connection on;
157 
158     keepalive_timeout 75s;
159     keepalive_requests 100;
160 
161     client_body_temp_path /tmp/client-body;
162     fastcgi_temp_path /tmp/fastcgi-temp;
163     proxy_temp_path /tmp/proxy-temp;
164 
165     client_header_buffer_size 1k;
166     client_header_timeout 60s;
167     large_client_header_buffers 4 8k;
168     client_body_buffer_size 8k;
169     client_body_timeout 60s;
170 
171     http2_max_concurrent_streams 128;
172 
173     types_hash_max_size 2048;
174     server_names_hash_max_size 1024;
175     server_names_hash_bucket_size 32;
176     map_hash_bucket_size 130;
177 
178     proxy_headers_hash_max_size 512;
179     proxy_headers_hash_bucket_size 64;
180 
181     variables_hash_bucket_size 256;
182     variables_hash_max_size 2048;
183 
184     underscores_in_headers off;
185     ignore_invalid_headers on;
186 
187     limit_req_status 503;
188     limit_conn_status 503;
189 
190     include /etc/nginx/mime.types;
191     default_type text/html;
192 
193     gzip on;
194     gzip_comp_level 5;
195     gzip_http_version 1.1;
196     gzip_min_length 256;
197     gzip_types application/atom+xml application/javascript application/x-javascript application/json application/rss+xml application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/svg+xml image/x-icon text/css text/javascript text/plain text/x-component;
198     gzip_proxied any;
199     gzip_vary on;
200 
201     # Custom headers for response
202 
203     server_tokens on;
204 
205     # disable warnings
206     uninitialized_variable_warn off;
207 
208     # Additional available variables:
209     # $namespace
210     # $ingress_name
211     # $service_name
212     # $service_port
213     log_format upstreaminfo '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $request_length $request_time [$proxy_upstream_name] [$proxy_alternative_upstream_name] $upstream_addr $upstream_response_length $upstream_response_time $upstream_status $req_id';
214 
215     map $request_uri $loggable {
216 
217         default 1;
218     }
219 
220     access_log /var/log/nginx/access.log upstreaminfo if=$loggable;
221 
222     error_log /var/log/nginx/error.log notice;
223 
224     resolver 10.96.0.10 valid=30s;
225 
226     # See https://www.nginx.com/blog/websocket-nginx
227     map $http_upgrade $connection_upgrade {
228         default upgrade;
229 
230         # See http://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive
231         '' '';
232 
233     }
234 
235     # Reverse proxies can detect if a client provides a X-Request-ID header, and pass it on to the backend server.
236     # If no such header is provided, it can provide a random value.
237     map $http_x_request_id $req_id {
238         default $http_x_request_id;
239 
240         ""
241         $request_id;
242 
243     }
244 
245     # Create a variable that contains the literal $ character.
246     # This works because the geo module will not resolve variables.
247     geo $literal_dollar {
248         default "$";
249     }
250 
251     server_name_in_redirect off;
252     port_in_redirect off;
253 
254     ssl_protocols TLSv1.2;
255     ssl_early_data off;
256 
257     # turn on session caching to drastically improve performance
258 
259     ssl_session_cache builtin:1000 shared:
260     SSL:10m;
261     ssl_session_timeout 10m;
262 
263     # allow configuring ssl session tickets
264     ssl_session_tickets on;
265 
266     # slightly reduce the time-to-first-byte
267     ssl_buffer_size 4k;
268 
269     # allow configuring custom ssl ciphers
270     ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
271     ssl_prefer_server_ciphers on;
272 
273     ssl_ecdh_curve auto;
274 
275     # PEM sha: 24abab98ff48f9134bf7ede71a6f651b32494be6
276     ssl_certificate /etc/ingress-controller/ssl/default-fake-certificate.pem;
277     ssl_certificate_key /etc/ingress-controller/ssl/default-fake-certificate.pem;
278 
279     xquic_ssl_certificate /etc/ingress-controller/ssl/default-fake-certificate.pem;
280     xquic_ssl_certificate_key /etc/ingress-controller/ssl/default-fake-certificate.pem;
281 
282     proxy_ssl_session_reuse on;
283 
284     upstream upstream_balancer {
285         ### Attention!!!
286         #
287         # We no longer create "upstream" section for every backend.
288         # Backends are handled dynamically using Lua. If you would like to debug
289         # and see what backends ingress-nginx has in its memory you can
290         # install our kubectl plugin https://kubernetes.github.io/ingress-nginx/kubectl-plugin.
291         # Once you have the plugin you can use "kubectl ingress-nginx backends" command to
292         # inspect current backends.
293         #
294         ###
295 
296         server 0.0.0.1;
297         # placeholder
298 
299         balancer_by_lua_block {
300             balancer.balance()
301         }
302 
303         keepalive 32;
304 
305         keepalive_timeout 60s;
306         keepalive_requests 100;
307 
308     }
309 
310     # Cache for internal auth checks
311     proxy_cache_path /tmp/nginx-cache-auth levels=1:2 keys_zone=auth_cache:10m max_size=128m inactive=30m use_temp_path=off;
312 
313     # Global filters
314 
315     ## start server _
316     server {
317         server_name _ ;
318 
319         listen 80 default_server reuseport backlog=4096 ;
320         listen [::]:80 default_server reuseport backlog=4096 ;
321         listen 443 default_server reuseport backlog=4096 ssl http2 ;
322         listen [::]:443 default_server reuseport backlog=4096 ssl http2 ;
323         listen 443 default_server reuseport backlog=4096 xquic ;
324         listen [::]:443 default_server reuseport backlog=4096 xquic ;
325 
326         ingress_gateway shm_service_cfg;
327         ingress_gateway_metadata "ssl-protocols" $metadata_ssl_protocols;
328 
329         # set log host
330         set $log_host $host;
331 
332         set $proxy_upstream_name "-";
333 
334         ssl_certificate_by_lua_block {
335             certificate.call()
336         }
337 
338         location = /status.tengine {
339             if ($host !~* "^\d{1,3}(\.\d{1,3}){3}|^status\.tengine\.com$") {
340                 return 404;
341                 break;
342             }
343             sysguard off;
344             access_log off;
345             root /etc/nginx/htdocs;
346         }
347 
348         location / {
349 
350             ingress_gateway_metadata "namespace" $metadata_namespace;
351             ingress_gateway_metadata "ingress_name" $metadata_ingress_name;
352             ingress_gateway_metadata "service_name" $metadata_service_name;
353             ingress_gateway_metadata "service_port" $metadata_service_port;
354             ingress_gateway_metadata "location_path" $metadata_location_path;
355             set $namespace $metadata_namespace;
356             set $ingress_name $metadata_ingress_name;
357             set $service_name $metadata_service_name;
358             set $service_port $metadata_service_port;
359             set $location_path $metadata_location_path;
360 
361 
362             set $upstream_read_time $ingress_read_timeout;
363             set $https_host_mode $ingress_force_https;
364             include /etc/nginx/apps/ssl.conf;
365             set $proxy_upstream_name $ingress_route_target;
366             add_header Ups-Target-Key $ingress_route_target always;
367             add_header X-protocol $server_protocol always;
368 
369             add_header Alt-Svc 'h3=":443"; ma=2592000,h3-29=":443"; ma=2592000' always;
370 
371             if ($ingress_route_target = "") {
372                 return 404;
373                 break;
374             }
375 
376             # be careful with `access_by_lua_block` and `satisfy any` directives as satisfy any
377             # will always succeed when there's `access_by_lua_block` that does not have any lua code doing `ngx.exit(ngx.DECLINED)`
378             # other authentication method such as basic auth or external auth useless - all requests will be allowed.
379             #access_by_lua_block {
380             #}
381 
382             header_filter_by_lua_block {
383                 lua_ingress.header()
384                 plugins.run()
385             }
386 
387             body_filter_by_lua_block {
388             }
389 
390             log_by_lua_block {
391                 balancer.log()
392 
393                 monitor.call()
394 
395                 plugins.run()
396             }
397 
398             sysguard off;
399 
400             port_in_redirect off;
401 
402             set $balancer_ewma_score -1;
403 
404             set $proxy_host $proxy_upstream_name;
405             set $pass_access_scheme $scheme;
406 
407             set $pass_server_port $server_port;
408 
409             set $best_http_host $http_host;
410             set $pass_port $pass_server_port;
411 
412             set $proxy_alternative_upstream_name "";
413 
414             # CORS
415 
416             ingress_gateway_metadata "enable-cors" $metadata_enable_cors;
417             ingress_gateway_metadata "cors-allow-origin" $metadata_cors_allow_origin;
418             ingress_gateway_metadata "cors-max-age" $metadata_cors_max_age;
419             ingress_gateway_metadata "cors-allow-credentials" $metadata_cors_allow_credentials;
420             ingress_gateway_metadata "cors-allow-methods" $metadata_cors_allow_methods;
421             ingress_gateway_metadata "cors-allow-headers" $metadata_cors_allow_headers;
422 
423             set $enable_cors_options_credentials "${metadata_enable_cors}_${request_method}_${metadata_cors_allow_credentials}";
424             set $metadata_enable_cors_credentials "${metadata_enable_cors}_${metadata_cors_allow_credentials}";
425 
426             client_max_body_size 1m;
427 
428             proxy_set_header Host $best_http_host;
429 
430             # Pass the extracted client certificate to the backend
431 
432             # Allow websocket connections
433             proxy_set_header Upgrade $http_upgrade;
434 
435             proxy_set_header Connection $connection_upgrade;
436 
437             proxy_set_header X-Request-ID $req_id;
438             proxy_set_header X-Real-IP $remote_addr;
439 
440             proxy_set_header X-Forwarded-For $remote_addr;
441 
442             proxy_set_header X-Forwarded-Host $best_http_host;
443             proxy_set_header X-Forwarded-Port $pass_port;
444             proxy_set_header X-Forwarded-Proto $pass_access_scheme;
445 
446             proxy_set_header X-Scheme $pass_access_scheme;
447 
448             # Pass the original X-Forwarded-For
449             proxy_set_header X-Original-Forwarded-For $http_x_forwarded_for;
450 
451             # tengine headers
452             proxy_set_header X-Real-Scheme $scheme;
453             proxy_set_header Web-Server-Type tengine-ingress;
454             proxy_set_header X-Request-From tengine-ingress;
455             proxy_set_header WL-Proxy-Client-IP $remote_addr;
456             proxy_set_header Proxy-X-Forwarded-For $proxy_add_x_forwarded_for;
457             proxy_set_header X-Client-Http2 $http2;
458             proxy_set_header X-Connection $x_connection;
459 
460             # mitigate HTTPoxy Vulnerability
461             # https://www.nginx.com/blog/mitigating-the-httpoxy-vulnerability-with-nginx/
462             proxy_set_header Proxy "";
463 
464             # Custom headers to proxied server
465 
466             if ($enable_cors_options_credentials = "true_OPTIONS_true") {
467                 # Cors Preflight methods needs additional options and different Return Code
468                 more_set_headers 'Access-Control-Allow-Origin: $metadata_cors_allow_origin';
469                 more_set_headers 'Access-Control-Allow-Credentials: $metadata_cors_allow_credentials';
470                 more_set_headers 'Access-Control-Allow-Methods: $metadata_cors_allow_methods';
471                 more_set_headers 'Access-Control-Allow-Headers: $metadata_cors_allow_headers';
472                 more_set_headers 'Access-Control-Max-Age: $metadata_cors_max_age';
473                 more_set_headers 'Content-Type: text/plain charset=UTF-8';
474                 more_set_headers 'Content-Length: 0';
475                 return 204;
476             }
477 
478             if ($enable_cors_options_credentials = "true_OPTIONS_false") {
479                 # Cors Preflight methods needs additional options and different Return Code
480                 more_set_headers 'Access-Control-Allow-Origin: $metadata_cors_allow_origin';
481                 more_set_headers 'Access-Control-Allow-Methods: $metadata_cors_allow_methods';
482                 more_set_headers 'Access-Control-Allow-Headers: $metadata_cors_allow_headers';
483                 more_set_headers 'Access-Control-Max-Age: $metadata_cors_max_age';
484                 more_set_headers 'Content-Type: text/plain charset=UTF-8';
485                 more_set_headers 'Content-Length: 0';
486                 return 204;
487             }
488 
489             if ($metadata_enable_cors_credentials = "true_true") {
490                 more_set_headers 'Access-Control-Allow-Origin: $metadata_cors_allow_origin';
491                 more_set_headers 'Access-Control-Allow-Credentials: $metadata_cors_allow_credentials';
492                 more_set_headers 'Access-Control-Allow-Methods: $metadata_cors_allow_methods';
493                 more_set_headers 'Access-Control-Allow-Headers: $metadata_cors_allow_headers';
494             }
495 
496             if ($metadata_enable_cors_credentials = "true_false") {
497                 more_set_headers 'Access-Control-Allow-Origin: $metadata_cors_allow_origin';
498                 more_set_headers 'Access-Control-Allow-Methods: $metadata_cors_allow_methods';
499                 more_set_headers 'Access-Control-Allow-Headers: $metadata_cors_allow_headers';
500             }
501 
502             proxy_connect_timeout 5s;
503             proxy_send_timeout 60s;
504             proxy_read_timeout 60s;
505 
506             proxy_buffering off;
507             proxy_buffer_size 4k;
508             proxy_buffers 4 4k;
509 
510             proxy_max_temp_file_size 1024m;
511 
512             proxy_request_buffering on;
513             proxy_http_version 1.1;
514 
515             proxy_cookie_domain off;
516             proxy_cookie_path off;
517 
518             # In case of errors try the next upstream server before returning an error
519             proxy_next_upstream error timeout;
520             proxy_next_upstream_timeout 0;
521             proxy_next_upstream_tries 3;
522 
523             proxy_pass http://upstream_balancer;
524 
525             proxy_redirect off;
526 
527         }
528 
529         location /robots.txt {
530             header_filter_by_lua_block {
531                 lua_ingress.header()
532                 plugins.run()
533             }
534 
535             root /etc/nginx/htdocs;
536 
537             sysguard off;
538             set $log_host "robots.tengine.com";
539             proxy_set_header Host $http_host;
540             proxy_set_header X-Request-From tengine-ingress;
541 
542             set $upstream_read_time $ingress_read_timeout;
543             set $https_host_mode $ingress_force_https;
544             include /etc/nginx/apps/ssl.conf;
545             set $proxy_upstream_name $ingress_route_target;
546             add_header Ups-Target-Key $ingress_route_target always;
547             add_header X-protocol $server_protocol always;
548 
549             add_header Alt-Svc 'h3=":443"; ma=2592000,h3-29=":443"; ma=2592000' always;
550 
551             set $https_use_timing "*";
552             if ($ingress_route_target = "") {
553                 return 404;
554                 break;
555             }
556             ingress_gateway_metadata "disable-robots" $metadata_disable_robots;
557             if ($metadata_disable_robots = "false") {
558                 proxy_pass http://upstream_balancer;
559             }
560 
561         }
562 
563         # health checks in cloud providers require the use of port 80
564         location /healthz {
565 
566             access_log off;
567             return 200;
568         }
569 
570         # this is required to avoid error if nginx is being monitored
571         # with an external software (like sysdig)
572         location /nginx_status {
573 
574             allow 127.0.0.1;
575 
576             allow ::1;
577 
578             deny all;
579 
580             sysguard off;
581             access_log off;
582             stub_status on;
583         }
584 
585         location /traffic_status {
586 
587             allow 127.0.0.1;
588 
589             allow ::1;
590 
591             deny all;
592 
593             sysguard off;
594             access_log off;
595             req_status_show;
596         }
597 
598     }
599     ## end server _
600 
601     # backend for when default-backend-service is not configured or it does not have endpoints
602     server {
603         listen 8181 default_server reuseport backlog=4096;
604         listen [::]:8181 default_server reuseport backlog=4096;
605         set $proxy_upstream_name "internal";
606 
607         access_log off;
608 
609         location / {
610             return 404;
611         }
612     }
613 
614     # default server, used for NGINX healthcheck and access to nginx stats
615     server {
616         listen 127.0.0.1:10246;
617         server_name status.tengine.com;
618         set $proxy_upstream_name "internal";
619 
620         sysguard off;
621 
622         keepalive_timeout 0;
623         gzip off;
624 
625         access_log off;
626 
627         if ($host !~* "^\d{1,3}(\.\d{1,3}){3}|^status\.tengine\.com$") {
628             set $log_host "notfound";
629             return 404;
630             break;
631         }
632 
633         location /healthz {
634             return 200;
635         }
636 
637         location /is-dynamic-lb-initialized {
638             content_by_lua_block {
639                 local configuration = require("configuration")
640                 local backend_data = configuration.get_backends_data()
641                 if not backend_data then
642                 ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
643                 return
644                 end
645 
646                 ngx.say("OK")
647                 ngx.exit(ngx.HTTP_OK)
648             }
649         }
650 
651         location /nginx_status {
652             stub_status on;
653         }
654 
655         location /configuration {
656             client_max_body_size 21m;
657             client_body_buffer_size 21m;
658             proxy_buffering off;
659 
660             content_by_lua_block {
661                 configuration.call()
662             }
663         }
664 
665         location / {
666             content_by_lua_block {
667                 ngx.exit(ngx.HTTP_NOT_FOUND)
668             }
669         }
670 
671         # for health check on alibaba
672         location = /status.tengine {
673             root /etc/nginx/htdocs;
674         }
675 
676         location = /traffic_status {
677             allow 10.0.0.0/8;
678             allow 11.0.0.0/8;
679             allow 172.16.0.0/12;
680             allow 127.0.0.1/32;
681             allow 192.168.0.0/16;
682             deny all;
683             req_status_show;
684         }
685     }
686 }
687 
688 stream {
689     lua_package_path "/etc/nginx/lua/?.lua;/etc/nginx/lua/vendor/?.lua;;";
690 
691     lua_shared_dict tcp_udp_configuration_data 5M;
692 
693     init_by_lua_block {
694         collectgarbage("collect")
695 
696         -- init modules
697         local ok, res
698 
699         ok, res = pcall(require, "configuration")
700         if not ok then
701         error("require failed: " .. tostring(res))
702         else
703         configuration = res
704         end
705 
706         ok, res = pcall(require, "tcp_udp_configuration")
707         if not ok then
708         error("require failed: " .. tostring(res))
709         else
710         tcp_udp_configuration = res
711         end
712 
713         ok, res = pcall(require, "tcp_udp_balancer")
714         if not ok then
715         error("require failed: " .. tostring(res))
716         else
717         tcp_udp_balancer = res
718         end
719     }
720 
721     init_worker_by_lua_block {
722         tcp_udp_balancer.init_worker()
723     }
724 
725     lua_add_variable $proxy_upstream_name;
726 
727     log_format log_stream '[$remote_addr] [$time_local] $protocol $status $bytes_sent $bytes_received $session_time';
728 
729     access_log /var/log/nginx/access.log log_stream ;
730 
731     error_log /var/log/nginx/error.log;
732 
733     upstream upstream_balancer {
734         server 0.0.0.1:1234;
735         # placeholder
736 
737         balancer_by_lua_block {
738             tcp_udp_balancer.balance()
739         }
740     }
741 
742     server {
743         listen 127.0.0.1:10247;
744 
745         access_log off;
746 
747         content_by_lua_block {
748             tcp_udp_configuration.call()
749         }
750     }
751 
752     # TCP services
753 
754     # UDP services
755 
756 }
nginx.conf

配置文件的的lua代码,使用了以下库函数。它们定义在tengine-ingrss中,安装在下图所示的目录位置。

 阅读上述lua会发现,其中使用了ngx模块。如下图:

 该模块的定义,在nginx的C程序代码中,见函数ngx_http_lua_init_globals()->ngx_http_lua_inject_ngx_api()

 

 

 上图中的lua_*系列函数是由谁提供的呢?

查看代码中include了 lua.h, 通过前文的资料得知依赖 LuaJIT,加入该模块编译nginx,也可以看见同样的报错提示信息:

sudo ./configure --add-module=/home/tong/Source/tengine-tengine-3.1.0/modules/ngx_http_lua_module/

sudo ./configure --with-http_lua_module

 通过LuaJIT的源码,也能观察到相关的函数声明:

https://github.com/openresty/luajit2/blob/v2.1-agentzh/src/lua.h

使用apt安装openresty-luajit

sudo apt install libluajit2-5.1-dev

 

软件包内容

dpkg -L libluajit2-5.1-2:amd64 libluajit2-5.1-common libluajit2-5.1-dev:amd64

/.
/usr
/usr/lib
/usr/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu/libluajit-5.1.so.2.1.0
/usr/share
/usr/share/doc
/usr/share/doc/libluajit2-5.1-2
/usr/share/doc/libluajit2-5.1-2/changelog.Debian.gz
/usr/share/doc/libluajit2-5.1-2/copyright
/usr/share/lintian
/usr/share/lintian/overrides
/usr/share/lintian/overrides/libluajit2-5.1-2
/usr/lib/x86_64-linux-gnu/libluajit-5.1.so.2

/.
/usr
/usr/share
/usr/share/doc
/usr/share/doc/libluajit2-5.1-common
/usr/share/doc/libluajit2-5.1-common/changelog.Debian.gz
/usr/share/doc/libluajit2-5.1-common/copyright
/usr/share/luajit-2.1.0-beta3
/usr/share/luajit-2.1.0-beta3/jit
/usr/share/luajit-2.1.0-beta3/jit/bc.lua
/usr/share/luajit-2.1.0-beta3/jit/bcsave.lua
/usr/share/luajit-2.1.0-beta3/jit/dis_arm.lua
/usr/share/luajit-2.1.0-beta3/jit/dis_arm64.lua
/usr/share/luajit-2.1.0-beta3/jit/dis_arm64be.lua
/usr/share/luajit-2.1.0-beta3/jit/dis_mips.lua
/usr/share/luajit-2.1.0-beta3/jit/dis_mips64.lua
/usr/share/luajit-2.1.0-beta3/jit/dis_mips64el.lua
/usr/share/luajit-2.1.0-beta3/jit/dis_mipsel.lua
/usr/share/luajit-2.1.0-beta3/jit/dis_ppc.lua
/usr/share/luajit-2.1.0-beta3/jit/dis_x64.lua
/usr/share/luajit-2.1.0-beta3/jit/dis_x86.lua
/usr/share/luajit-2.1.0-beta3/jit/dump.lua
/usr/share/luajit-2.1.0-beta3/jit/p.lua
/usr/share/luajit-2.1.0-beta3/jit/v.lua
/usr/share/luajit-2.1.0-beta3/jit/vmdef.lua
/usr/share/luajit-2.1.0-beta3/jit/zone.lua

/.
/usr
/usr/include
/usr/include/luajit-2.1
/usr/include/luajit-2.1/lauxlib.h
/usr/include/luajit-2.1/lua.h
/usr/include/luajit-2.1/lua.hpp
/usr/include/luajit-2.1/luaconf.h
/usr/include/luajit-2.1/luajit.h
/usr/include/luajit-2.1/lualib.h
/usr/lib
/usr/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu/libluajit-5.1.a
/usr/lib/x86_64-linux-gnu/pkgconfig
/usr/lib/x86_64-linux-gnu/pkgconfig/luajit.pc
/usr/share
/usr/share/doc
/usr/share/doc/libluajit2-5.1-dev
/usr/share/doc/libluajit2-5.1-dev/copyright
/usr/lib/x86_64-linux-gnu/libluajit-5.1.so
/usr/share/doc/libluajit2-5.1-dev/changelog.Debian.gz
包内容

装完以后增加两个参数之后再编译

sudo ./configure --with-http_lua_module --with-luajit-inc=/usr/include/luajit-2.1/  --with-luajit-lib=/usr/lib/x86_64-linux-gnu/
sudo make

 

babassl

 使用前文提到的tengine的nginx.conf进行运行测试。新增加了几个编译选项.

tengine用来babassl,现在叫铜锁,https://github.com/Tongsuo-Project/Tongsuo ,支持国密

 

tongsuo的安装方法

下载解压:
wget https://github.com/Tongsuo-Project/Tongsuo/archive/refs/heads/8.4-stable.zip

 

 编译命令

sudo ./configure --with-http_lua_module --with-luajit-inc=/usr/include/luajit-2.1/  --with-luajit-lib=/usr/lib/x86_64-linux-gnu/ --add-module=modules
/ngx_ingress_module/ --with-openssl=/home/tong/Source/Tongsuo-8.4-stable/ --add-module=modules/mod_common --add-module=modules/mod_strategy --with-cc-opt="-Wno-error=cast-function-type -g -O0" -
-with-http_v2_module

 

共享内存

 运行

注释了一部分不需要的配置项之后,测试可以跑起来,手工创建共享内存。

dd if=/dev/zero of=/dev/shm/ShmServiceCfg bs=1M count=256
touch /etc/nginx/shm_service_cfg.lock

 

 运行发现有报错,需要resty组件

 阅读代码可以看见,在函数 ngx_http_lua_init_vm 中显示声明了对 resty.core 的依赖:

 

安装 lua-resty-core

源码安装参考:https://github.com/openresty/lua-resty-core

 

下载源码:wget https://github.com/openresty/lua-resty-core/archive/refs/tags/v0.1.27.zip

base.lua 代码里边有个强制的版本依赖,所以要找对相应版本进行下载。

https://github.com/openresty/lua-resty-core/blob/v0.1.27/lib/resty/core/base.lua

 

sudo make install LUA_LIB_DIR=/usr/local/share/lua/5.1

 

resty-core依赖 resty-lrucache

sudo apt install lua-resty-lrucache

 

继续安装stream相关的lua模块

同样resty.core中有版本要求,下载正确的版本,如果版本不对,运行时会提示,它依赖的版本号

wget https://github.com/openresty/stream-lua-nginx-module/archive/refs/tags/v0.0.16.zip

解压后增加config参数再编译

--with-stream --with-stream_ssl_module --add-module=/home/tong/Source/stream-lua-nginx-module-0.0.13/

 

ingress的lua

拷贝ingress的lua到nginx的配置文件目录

sudo cp -a /home/tong/Source/tengine-ingress-Tengine-Ingress-v1.1.0/rootfs/etc/nginx/lua /etc/nginx/lua

 

lua-cjson

安装:sudo apt install lua-cjson

 

resty.dns.resolver

下载:wget https://github.com/openresty/lua-resty-dns/archive/refs/tags/v0.23.zip

 安装:sudo make install LUA_LIB_DIR=/usr/local/share/lua/5.1

 

resty.roundrobin

安装方法同上:

wget https://github.com/openresty/lua-resty-balancer/archive/refs/tags/v0.05.zip

 

报错:

nginx: [error] init_by_lua error: init_by_lua(tengine-ingress-nginx.conf:47):39: require failed: /usr/local/share/lua/5.1/resty/chash.lua:89: can not load librestychash
stack traceback:
        [C]: in function 'error'
        init_by_lua(tengine-ingress-nginx.conf:47):39: in main chunk

参考安装指引:https://github.com/openresty/lua-resty-balancer#installation

在配置文件中添加如下行:

lua_package_cpath "/path/to/lua-resty-chash/?.so;;";

 

lua-resty-cookie

wget https://github.com/cloudflare/lua-resty-cookie/archive/refs/tags/v0.1.0.zip

安装方法同上

 

lua-resty-lock

wget https://github.com/openresty/lua-resty-lock/archive/refs/tags/v0.09.zip

安装方法同上

 

所有lua包依赖都可以在ingress的docker build.sh 中找到:

https://github.com/alibaba/tengine-ingress/blob/master/images/nginx/rootfs/build.sh#L134

 

最终的编译选项与命令行

sudo ./configure --with-http_lua_module --with-luajit-inc=/usr/include/luajit-2.1/  --with-luajit-lib=/usr/lib/x86_64-linux-gnu/ --add-module=modules/mod_common --add-module=modules/mod_strategy --add-module=modules/ngx_ingress_module/ --with-openssl=/home/tong/Source/Tongsuo-8.4-stable/ --with-cc-opt="-Wno-error=cast-function-type -g -O0" --with-http_v2_module --with-stream --with-stream_ssl_module --add-module=/home/tong/Source/stream-lua-nginx-module-0.0.13/
sudo ./objs/nginx -c /etc/nginx/tengine-ingress-nginx.conf

 

 运行效果

 

 

 

 

淘宝开源的sar:https://github.com/alibaba/tsar

posted on 2025-03-10 22:01  toong  阅读(2)  评论(0)    收藏  举报