OpenResty 에서 전역 변수의 사용 을 피해 야 합 니 다.

4618 단어 openresty
lua-variable-scope
코드 에서 모듈 을 가 져 올 때 세부 사항 을 주의해 야 합 니 다. 설명 은 다음 과 같은 형식 을 사용 합 니 다.
 local xxx = require('xxx')

대신:
require('xxx')

이 유 는 다음 과 같다. 디자인 적 으로 볼 때 전체 환경의 생명 주기 와 Nginx 가 요청 한 생명 주 기 는 같다.세 션 격 리 를 위해 요청 마다 Lua 전역 변수 환경 이 있 습 니 다.Lua 모듈 은 처음 서버 에 전 화 를 걸 어 달라 고 요 청 했 을 때 불 러 와 package.loaded 테이블 에 만들어 진 require() 캐 시 를 통 해 후속 코드 를 재 활용 했다.또한 일부 Lua 모듈 에 있 는 module() 한계 문제 가 존재 합 니 다. 로 딩 이 완 료 된 모듈 에 대해 전역 표 변 수 를 설정 하지만 이 전역 변 수 는 요청 처리 마지막 에 비 워 지고 모든 후속 요청 은 자신 만 의 (깨끗 한) 전역 공간 을 가지 고 있 습 니 다.그래서 방문 nil 값 때문에 Lua 이상 을 받 을 수 있 습 니 다.
일반적으로 ngxlua 의 컨 텍스트 에서 Lua 전역 변 수 를 사용 하 는 것 은 정말 좋 은 생각 이 아 닙 니 다.
  • 전체 변 수 를 남용 하 는 부작용 은 동시 다발 장면 에 부작용 을 일 으 킬 수 있다. 예 를 들 어 사용자 가 이런 변 수 를 현지 변수 로 볼 때;
  • Lua 의 전역 변 수 는 전역 환경 (하나의 Lua 표 일 뿐) 을 위로 찾 아야 하 며 대가 가 비교적 높다.
  • 일부 Lua 의 전역 변수 인용 은 맞 춤 법 오류 일 뿐 오류 가 발생 하여 조사 하기 어렵다.

  • 따라서 우 리 는 변 수 를 사용 할 때 항상 local 로 정의 하여 발효 범 위 를 제한 하 는 데 이유 가 있다.
    사용 도구 (lua - reling tool) [https://github.com/openresty/nginx-devel-utils/blob/master/lua-releng] 루 아 원본 파일 찾기:
    $ lua-releng     
    Checking use of Lua global variables in file lib/foo/bar.lua ...  
        1       [1489]  SETGLOBAL       7 -1    ; contains
        55      [1506]  GETGLOBAL       7 -3    ; setvar
        3       [1545]  GETGLOBAL       3 -4    ; varexpand
    

    상기 출력 설명 파일 lib/foo/bar.lua 의 1489 줄 은 contains 라 는 전역 변 수 를 기록 하고 1506 줄 은 setvar 라 는 전역 변 수 를 읽 으 며 1545 줄 은 varexpand 라 는 전역 변 수 를 읽 습 니 다.
    이 도 구 는 Lua 모듈 의 부분 변 수 를 모두 local 키워드 로 정의 할 수 있 습 니 다. 그렇지 않 으 면 런 타임 라 이브 러 리 를 던 집 니 다.이렇게 하면 유사 변수 와 같은 자원 의 경쟁 을 막 을 수 있다.이 유 는 참고 하 십시오 (Nginx Worker 내의 데이터 공유) [http://wiki.nginx.org/HttpLuaModule#Data_Sharing_within_an_Nginx_Worker]
    왕 원생 작가: agentzh
    English source:
    Lua Variable Scope
    Care must be taken when importing modules and this form should be used:
    
     local xxx = require('xxx')

    instead of the old deprecated form:
    
     require('xxx')

    Here is the reason: by design, the global environment has exactly the same lifetime as the Nginx request handler associated with it. Each request handler has its own set of Lua global variables and that is the idea of request isolation. The Lua module is actually loaded by the first Nginx request handler and is cached by the require() built-in in the package.loaded table for later reference, and the module() builtin used by some Lua modules has the side effect of setting a global variable to the loaded module table. But this global variable will be cleared at the end of the request handler, and every subsequent request handler all has its own (clean) global environment. So one will get Lua exception for accessing the nil value.
    Generally, use of Lua global variables is a really really bad idea in the context of ngx_lua because
  • misuse of Lua globals has very bad side effects for concurrent requests when these variables are actually supposed to be local only,
  • Lua global variables require Lua table look-up in the global environment (which is just a Lua table), which is kinda expensive, and
  • some Lua global variable references are just typos, which are hard to debug.

  • It's highly recommended to always declare them via "local" in the scope that is reasonable.
    To find out all the uses of Lua global variables in your Lua code, you can run the lua-releng tool across all your .lua source files:
    $ lua-releng
    Checking use of Lua global variables in file lib/foo/bar.lua ...
            1       [1489]  SETGLOBAL       7 -1    ; contains
            55      [1506]  GETGLOBAL       7 -3    ; setvar
            3       [1545]  GETGLOBAL       3 -4    ; varexpand
    

    The output says that the line 1489 of file lib/foo/bar.lua writes to a global variable named contains , the line 1506 reads from the global variable setvar , and line 1545 reads the global varexpand .
    This tool will guarantee that local variables in the Lua module functions are all declared with the local keyword, otherwise a runtime exception will be thrown. It prevents undesirable race conditions while accessing such variables. See Data Sharing within an Nginx Worker for the reasons behind this.
    Back to TOC

    좋은 웹페이지 즐겨찾기