-
Notifications
You must be signed in to change notification settings - Fork 765
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
如何在网站里加入自定义的'X-Uid:30'请求头? #3
Comments
这里golang开发的后端服务器指的是否是upstream server,而proxy server依然使用的是nginx?能否具体说下,为网页添加自定义请求头是什么意思呢? |
proxy server 就是你提供的ABTestingGateway .upstream server 就是我这边用golang开发的app server.
运行:
可以分流到beta1 的app server. 现在我的问题是: 这里是通过 curl -H 'X-Uid:1024' 这个请求头进行分流的. 但是我有什么方法设置浏览器里网页的请求头? 来达到分流的目的? |
你好。默认情况下浏览器不会发送多余的header,除非是cookie。如果想通过浏览器网页发送请求头,可以通过javascript实现,其他定制的客户端,比如curl、自己写的client或者手机客户端,都可以编程实现。 如果你是想压测或者什么的,可以使用wrk,wrk可以通过内嵌的lua脚本向请求添加 header。 |
好的,谢谢,我昨晚稍改了下lua的代码,现在加了个uid的cookie.这样应该可以去实现分流.
|
cookie可以被认为一种特殊的header。 |
不过我修改了代码之后遇到另外一个问题:
修改的代码: _M.get = function()
-- local u = ngx.req.get_headers()["X-Uid"]
-- ngx.log(ngx.ERR,"X-Uid")
-- ngx.log(ngx.ERR,ngx.req.get_headers()["X-Uid"])
-- ngx.log(ngx.ERR,"cookie-uid")
-- ngx.log(ngx.ERR,ngx.var.cookie_uid)
local u = ngx.var.cookie_uid ------`还有就是local 是加到这里可以避免你上面说的内存问题吗?`
return u
end 遇到的问题:
不知道什么原因造成的? 这个问题导致只有设置的uid才能访问,其他都返回 500 Internal Server Error . |
你好。 $ curl http://127.0.0.1:8030/admin/policy/set -d '{"divtype":"uidappoint","divdata":[{"uidset":["1"], "upstream":"beta1"}]}'
{"errcode":200,"errinfo":"success the id of new policy is 1"}
$ curl http://127.0.0.1:8030/admin/runtime/set?policyid=1
{"errcode":200,"errinfo":"success "} 按照你提供的代码,修改lib/abtesting/userinfo/uidParser.lua内容为: local _M = {
_VERSION = '0.01'
}
--_M.get = function()
-- local u = ngx.req.get_headers()["X-Uid"]
-- return u
--end
--
_M.get = function()
-- local u = ngx.req.get_headers()["X-Uid"]
-- ngx.log(ngx.ERR,"X-Uid")
-- ngx.log(ngx.ERR,ngx.req.get_headers()["X-Uid"])
-- ngx.log(ngx.ERR,"cookie-uid")
-- ngx.log(ngx.ERR,ngx.var.cookie_uid)
local u = ngx.var.cookie_uid ------`还有就是local 是加到这里可以避免你上面说的内存问题吗?`
return u
end
return _M 检验结果 $ curl 127.0.0.1:8030/ --cookie 'uid=1'
this is beta1 server 说明是正常运行的。 然后,根据你的错误提示, 2015/09/01 17:45:08 [error] 23001#0: *33262 lua entry thread aborted: runtime error: ...t/soft/ABTestingGateway/utils/../diversion/diversion.lua:238: bad argument #1 to '__newindex' (string, number, or nil expected, but got user data) diversion/diversion.lua的第238行左右代码是 if upstream then
ngx.var.backend = upstream --line 238
else
upstream = default_backend
end 再结合是__newindex方法错误(__newindex是修改table内容的lua metamethod,__index是访问table内容的lua metamethod,这里ngx.var可以看做是一个table,ngx.var.backend和ngx.var['backend']是一个东西),你应该是将一个这个upstream变量获取错了,你获取成了user data类型,而ngx.var.backend需要一个普通类型,比如number、string什么的。所以首先应该检查的是在238行之前,就是getUpstream函数的返回值,可能是user data类型的(提示:lua-resty-redis读取到的ngx.null就是一个user data,极有可能是他。ngx.null)。 从根源上来说,用user data类型对ngx.var.backend进行赋值的错误原因可以在ngx_lua源码看到,在ngx_lua/src/ngx_http_lua_variable.c中 static int
ngx_http_lua_var_set(lua_State *L)
{
...
/* we read the variable new value */
value_type = lua_type(L, 3);
switch (value_type) {
case LUA_TNUMBER:
case LUA_TSTRING:
p = (u_char *) luaL_checklstring(L, 3, &len);
val = ngx_palloc(r->pool, len);
if (val == NULL) {
return luaL_error(L, "memory allocation erorr");
}
ngx_memcpy(val, p, len);
break;
case LUA_TNIL:
/* undef the variable */
val = NULL;
len = 0;
break;
default:
msg = lua_pushfstring(L, "string, number, or nil expected, "
"but got %s", lua_typename(L, value_type));
return luaL_argerror(L, 1, msg);
}
...
} 当右值不是number、string或nil时,比如是table或者user data,会报错: string, number, or nil expected, but got %s / type 而且错误信息就是luaL_argerror函数打印的。 2015/09/01 17:45:08 [error] 23001#0: *33262 lua entry thread aborted: runtime error: ...t/soft/ABTestingGateway/utils/../diversion/diversion.lua:238: bad argument #1 to '__newindex' (string, number, or nil expected, but got user data) 最后 local u = ngx.var.cookie_uid ------`还有就是local 是加到这里可以避免你上面说的内存问题吗?` 答案是肯定的,这相当于只读取cookie_uid一次,缓存在lua虚拟机中,下次就不用再重新分配内容并读取数据了,直接从lua虚拟机读就好。 |
谢谢您这么详细的分析和解答. 原来diversion/diversion.lua的第238行 if upstream then --238
ngx.var.backend = upstream
else
upstream = default_backend
end 修改后的diversion/diversion.lua的第238行 if upstream ~= ngx.null and upstream then --238
ngx.var.backend = upstream
else
upstream = default_backend
end
|
不客气,最应该感谢你的使用和反馈,一个活的project必须是经过多人使用和检验的。 _M.getUpstream = function(self, uid)
if not tonumber(uid) then
return nil
end
local database, key = self.database, self.policyLib
local backend, err = database:hget(key, uid)
if not backend then error{ERRORINFO.REDIS_ERROR, err} end
if backend == ngx.nul then backend = nil end
return backend
end 请注意返回backend时我已经判断过是否为ngx.null的问题,所以我现在很好奇你的问题根源,能提供更多的信息或者最小实现吗? |
看了这段代码,我好像发现问题在哪里了: _M.getUpstream = function(self, uid)
if not tonumber(uid) then
return nil
end
local database, key = self.database, self.policyLib
local backend, err = database:hget(key, uid)
if not backend then error{ERRORINFO.REDIS_ERROR, err} end
if backend == ngx.nul then backend = nil end -- 这里的ngx.nul 是不是应该是ngx.null
return backend
end 因为我改的代码(diversion/diversion.lua)是ngx.null : if upstream ~= ngx.null and upstream then --238 ,这里的ngx.null
ngx.var.backend = upstream
else
upstream = default_backend
end 不过我奇怪最开始我测 获取head的"X-Uid"好像没有报错. |
好的吧,是我写错了,不好意思哈哈。我立刻改改。 |
@Michael2008S @BG2BKK |
你是想在location abc{}中配置分流功能是吧,之前我们的考虑都是在/下分流的。你的目的应该是想要访问/abc?q=sina的时候转发到upstream的请求是/?q=sina是吗? |
是的,由于上游业务不同url是不同的,且随着业务变动后期还会有新的url ,我想是不是会有一个url的模糊匹配方式,凡事满足127.0.0.1:8030/* 的请求 统统走你们提出的几种策略(这里假设是uid后缀) |
@Michael2008S @BG2BKK |
local u = ngx.var.cookie_uid ------ 请问下为何加了local之后就缓存到lua里面了?这是lua自己的特征还是openresty提供的特质?? |
我用的是golang开发的后端服务器,现在实例里面都是通过 curl 请求的测试是可以通过的,但是不知道怎么添加自定义的请求头?
有什么方法可以为网页添加自定义的请求头?
The text was updated successfully, but these errors were encountered: