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 }
配置文件的的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
浙公网安备 33010602011771号