You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by me...@apache.org on 2020/10/09 08:39:57 UTC
[apisix] branch master updated: bugfix: set random seed for each
worker process at `init_worker` phase,
only `init` phase is not enough. (#2357)
This is an automated email from the ASF dual-hosted git repository.
membphis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix.git
The following commit(s) were added to refs/heads/master by this push:
new 251625d bugfix: set random seed for each worker process at `init_worker` phase, only `init` phase is not enough. (#2357)
251625d is described below
commit 251625d8ab969b0b46d12041beff44f329e95321
Author: YuanSheng Wang <me...@gmail.com>
AuthorDate: Fri Oct 9 16:39:49 2020 +0800
bugfix: set random seed for each worker process at `init_worker` phase, only `init` phase is not enough. (#2357)
---
apisix/core/id.lua | 1 +
apisix/init.lua | 25 ++++++++++++-----
t/core/random.t | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++
t/stream-node/random.t | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 171 insertions(+), 7 deletions(-)
diff --git a/apisix/core/id.lua b/apisix/core/id.lua
index 5470f7a..d6e728d 100644
--- a/apisix/core/id.lua
+++ b/apisix/core/id.lua
@@ -65,6 +65,7 @@ function _M.init()
return
end
+ uuid.seed()
apisix_uid = uuid.generate_v4()
log.notice("not found apisix uid, generate a new one: ", apisix_uid)
diff --git a/apisix/init.lua b/apisix/init.lua
index 3d9ffea..5d773ab 100644
--- a/apisix/init.lua
+++ b/apisix/init.lua
@@ -63,13 +63,6 @@ function _M.http_init(args)
"maxrecord=8000", "sizemcode=64",
"maxmcode=4000", "maxirconst=1000")
- --
- local seed, err = core.utils.get_seed_from_urandom()
- if not seed then
- core.log.warn('failed to get seed from urandom: ', err)
- seed = ngx_now() * 1000 + ngx.worker.pid()
- end
- math.randomseed(seed)
parse_args(args)
core.id.init()
@@ -82,6 +75,15 @@ end
function _M.http_init_worker()
+ local seed, err = core.utils.get_seed_from_urandom()
+ if not seed then
+ core.log.warn('failed to get seed from urandom: ', err)
+ seed = ngx_now() * 1000 + ngx.worker.pid()
+ end
+ math.randomseed(seed)
+ -- for testing only
+ core.log.info("random test in [1, 10000]: ", math.random(1, 1000000))
+
local we = require("resty.worker.events")
local ok, err = we.configure({shm = "worker-events", interval = 0.1})
if not ok then
@@ -759,6 +761,15 @@ end
function _M.stream_init_worker()
core.log.info("enter stream_init_worker")
+ local seed, err = core.utils.get_seed_from_urandom()
+ if not seed then
+ core.log.warn('failed to get seed from urandom: ', err)
+ seed = ngx_now() * 1000 + ngx.worker.pid()
+ end
+ math.randomseed(seed)
+ -- for testing only
+ core.log.info("random stream test in [1, 10000]: ", math.random(1, 1000000))
+
router.stream_init_worker()
plugin.init_worker()
diff --git a/t/core/random.t b/t/core/random.t
new file mode 100644
index 0000000..8d7d403
--- /dev/null
+++ b/t/core/random.t
@@ -0,0 +1,76 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+use t::APISIX 'no_plan';
+
+master_on();
+workers(4);
+repeat_each(1);
+no_long_string();
+no_root_location();
+log_level("info");
+
+run_tests;
+
+__DATA__
+
+=== TEST 1: generate different random number in different worker process
+--- config
+ location /t {
+ content_by_lua_block {
+ local log_file = ngx.config.prefix() .. "logs/error.log"
+ local file = io.open(log_file, "r")
+ local log = file:read("*a")
+
+ local it, err = ngx.re.gmatch(log, [[random test in \[1, 10000\]: (\d+)]], "jom")
+ if not it then
+ ngx.log(ngx.ERR, "failed to gmatch: ", err)
+ return
+ end
+
+ local random_nums = {}
+ while true do
+ local m, err = it()
+ if err then
+ ngx.log(ngx.ERR, "error: ", err)
+ return
+ end
+
+ if not m then
+ break
+ end
+
+ -- found a match
+ table.insert(random_nums, m[1])
+ end
+
+ for i = 2, #random_nums do
+ local pre = random_nums[i - 1]
+ local cur = random_nums[i]
+ ngx.say("random[", i - 1, "] == random[", i, "]: ", pre == cur)
+ end
+ }
+ }
+--- request
+GET /t
+--- response_body
+random[1] == random[2]: false
+random[2] == random[3]: false
+random[3] == random[4]: false
+random[4] == random[5]: false
+--- no_error_log
+[error]
diff --git a/t/stream-node/random.t b/t/stream-node/random.t
new file mode 100644
index 0000000..80e5039
--- /dev/null
+++ b/t/stream-node/random.t
@@ -0,0 +1,76 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+use t::APISIX 'no_plan';
+
+master_on();
+workers(4);
+log_level('info');
+repeat_each(1);
+no_long_string();
+no_root_location();
+
+run_tests();
+
+__DATA__
+
+=== TEST 1: generate different random number in different worker process
+--- stream_enable
+--- config
+ location /test {
+ content_by_lua_block {
+ local log_file = ngx.config.prefix() .. "logs/error.log"
+ local file = io.open(log_file, "r")
+ local log = file:read("*a")
+
+ local it, err = ngx.re.gmatch(log, [[random stream test in \[1, 10000\]: (\d+)]], "jom")
+ if not it then
+ ngx.log(ngx.ERR, "failed to gmatch: ", err)
+ return
+ end
+
+ local random_nums = {}
+ while true do
+ local m, err = it()
+ if err then
+ ngx.log(ngx.ERR, "error: ", err)
+ return
+ end
+
+ if not m then
+ break
+ end
+
+ -- found a match
+ table.insert(random_nums, m[1])
+ end
+
+ for i = 2, #random_nums do
+ local pre = random_nums[i - 1]
+ local cur = random_nums[i]
+ ngx.say("random[", i - 1, "] == random[", i, "]: ", pre == cur)
+ end
+ }
+ }
+--- request
+GET /test
+--- response_body
+random[1] == random[2]: false
+random[2] == random[3]: false
+random[3] == random[4]: false
+random[4] == random[5]: false
+--- no_error_log
+[error]