链接https://stackoverflow.com/que...需要根据JWT的key和URL决定是否缓存HTTP请求,比如JWT中的payload:{"iss":"iss","sub":"sub","userGroupID":"{userGroupID}"}然后请求https://myapi.example.com/gro...{groupID}/cars如果userGroupID与groupID相同,则缓存,否则不缓存解决方案使用https://github.com/jiangwenyu...基于HAProxy的高性能缓存服务器1.下载搭建,需要luawgethttps://github.com/jiangwenyuan/nuster/releases/download/v1.8.8.2/nuster-1.8.8.2。tar.gzmakeTARGET=linux2628USE_ZLIB=1USE_OPENSSL=1USE_LUA=1LUA_LIB=/opt/lua-5.3.1/libLUA_INC=/opt/lua-5.3.1/include2。创建lua脚本,例如,jwt_group_match.lua--base64FROMhttp://lua-users.org/wiki/BaseSixtyFourlocalb='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'functiondec(data)data=string.gsub(data,'[^'..b..'=]','')return(data:gsub('.',function(x)if(x=='=')thenreturn''endlocalr,f='',(b:find(x)-1)fori=6,1,-1dor=r..(f%2^i-f%2^(i-1)>0and'1'or'0')结束返回r;end):gsub('%d%d%d?%d?%d?%d?%d?%d?',function(x)if(#x~=8)thenreturn''endlocalc=0fori=1,8doc=c+(x:sub(i,i)=='1'and2^(8-i)or0)endreturnstring.char(c)end))end--结束base64--jsonFROMhttps://gist.github.com/tylerneylon/59f4bcf316be525b30abjson={}functionkind_of(obj)iftype(obj)~='table'thenreturntype(obj)endlocali=1for_inpairs(obj)doifobj[i]~=niltheni=i+1elsereturn'table'endendifi==1thenreturn'table'elsereturn'array'endendfunctionescape_str(s)本地in_char={'\\','"','/','\b','\f','\n','\r','\t'}localout_char={'\\','"','/','b','f','n','r','t'}fori,cinipairs(in_char)dos=s:gsub(c,'\\'..out_char[i])endreturnsendfunctionskip_delim(str,pos,delim,err_if_missing)pos=pos+#str:match('^%s*',pos)ifstr:sub(pos,pos)~=delimtheniferr_if_missingthenerror('预期'..delim..'nearposition'..pos)endreturnpos,falseendreturnpos+1,trueendfunctionparse_str_val(str,pos,val)val=valor''localearly_end_error='解析字符串时发现输入结束。ifpos>#strthenerror(early_end_error)endlocalc=str:sub(pos,pos)ifc=='"'thenreturnval,pos+1endifc~='\\'thenreturnparse_str_val(str,pos+1,val..c)end--我们必须有一个\字符。localesc_map={b='\b',f='\f',n='\n',r='\r',t='\t'}localnextc=str:sub(pos+1,pos+1)ifnotnextcthenerror(early_end_error)endreturnparse_str_val(str,pos+2,val..(esc_map[nextc]或nextc))endfunctionparse_num_val(str,pos)localnum_str=str:match('^-?%d+%.?%d*[eE]?[+-]?%d*',pos)localval=tonumber(num_str)ifnotvalthenerror('Errorparsingnumberatposition'..pos..'.')endreturnval,pos+#num_strendjson.null={}--这是一个一次性表来表示零lvalue.functionjson.parse(str,pos,end_delim)pos=posor1ifpos>#strthenerror('Reachedunexpectedendofinput.')endlocalpos=pos+#str:match('^%s*',pos)--跳过空格。localfirst=str:sub(pos,pos)iffirst=='{'then--解析一个对象。localobj,key,delim_found={},true,truepos=pos+1whiletruedokey,pos=json.parse(str,pos,'}')ifkey==nilthenreturnobj,posend如果不是delim_foundthenerror('Commamissingbetweenobjectitems.')endpos=skip_delim(str,pos,':',true)--true->如果缺失则出错。obj[key],pos=json.parse(str,pos)pos,delim_found=skip_delim(str,pos,',')endelseiffirst=='['then--解析数组。localarr,val,delim_found={},true,truepos=pos+1whiletruedoval,pos=json.parse(str,pos,']')ifval==nil然后返回arr,posend如果不是delim_foundthenerror('逗号缺失betweenarrayitems.')endarr[#arr+1]=valpos,delim_found=skip_delim(str,pos,',')endelseiffirst=='"'then--解析字符串。returnparse_str_val(str,pos+1)elseiffirst=='-'orfirst:match('%d')then--解析一个数字returnparse_num_val(str,pos)elseiffirst==end_delimthen--对象或数组的结尾。returnnil,pos+1else--解析true,false,ornull.localliterals={['true']=true,['false']=false,['null']=json.null}forlit_str,lit_valinpairs(literals)dolocallit_end=pos+#lit_str-1ifstr:sub(pos,lit_end)==lit_str然后返回lit_val,lit_end+1endendlocalpos_info_str='position'..pos..':'..str:sub(pos,pos+10)error('无效的json语法开始于'..pos_info_str)endend--endjson--nusterjwtfunctionjwt_group_match(txn)localhdr=txn.http:req_get_headers()localjwt=hdr["jwt"]如果jwt==nil则返回falseend_,payload,_=jwt[0]:match"([^.]*)%.([^.]*)%.(.*)"如果payload==nil然后返回falseendlocalpayload_dec=dec(payload)localpayload_json=json.parse(payload_dec)iftxn.sf:path()=="/group/"..payload_json["userGroupID"].."/cars"然后返回trueendreturnfalseendcore.register_fetches(“jwt_group_match”,jwt_group_match)3。创建conf,比如说,nuster.confglobalnuster缓存在dict-size1mdata-size100mdebuglua-loadjwt_group_match.luafrontendweb1bind*:8080modehttpdefault_backendapp1backendapp1modehttphttp-requestset-var(req.jwt_group_match)lua.jwt_group_matchnuster规则组上的nuster缓存if{var(req.jwt_group_match)-mbool}servers1127.0.0.1:8000servers2127.0.0.1:80013。启动nuster./haproxy-fnuster.confTESTpayload:{"iss":"iss","sub":"sub","userGroupID":"nuster"}curlhttp://127.0.0.1:8080/group/nuster/cars--header"jwt:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJpc3MiLCJzdWIiOiJzdWIiLCJ1c2VyR3JvdXBJRCI6Im51c3RlciJ9.hPpqQS0d4T2BQP90ZDcgxnqJ0AHmwWFqZvdxu65X3FM"第一次运行[缓存]
