提交 3255355e 编写于 作者: L LeiHua

1.查询接口模块名为xdb;2.查询接口返回字符串;3.增加 apache 授权信息;4.调整基准测试数据来源

上级 32372fa8
# ip2region xdb erlang 查询客户端 # ip2region xdb erlang 查询客户端
### 简介
该bingding以erlang语言实现xdb查询客户端,基于Erlang OTP Application,查询逻辑由ip2region_worker工作进程实现,支持配多个工作进程来进行负载均衡。
### 应用配置
该应用可配置的参数在ip2region.app.src中,如下:
``` erlang
{env,[
{poolargs, [
{size, 1}, %% 工作进程默认数量
{max_overflow, 5} %% 工作进程最大数量
]}
]}
```
### 编译 ### 编译
...@@ -12,15 +25,20 @@ $ rebar3 compile ...@@ -12,15 +25,20 @@ $ rebar3 compile
$ rebar3 shell $ rebar3 shell
``` ```
在erlang节点中执行以下指令查询Ip地址信息 在erlang shell中调用xdb:search/1接口查询Ip地址信息, 该接口支持以list格式字符串、bianry格式字符串、tuple和整数表示的IP地址,如下
``` ```
1> ip2region:search("1.0.8.0"). 1> xdb:search("1.0.8.0").
#{city => <<229,185,191,229,183,158,229,184,130>>, [20013,22269,124,48,124,24191,19996,30465,124,24191,24030,
country => <<228,184,173,229,155,189>>, 24066,124,30005,20449]
isp => <<231,148,181,228,191,161>>,
province => <<229,185,191,228,184,156,231,156,129>>,
region => <<>>}
2> 2>
3> io:format("~ts~n", [xdb:search("1.0.8.0")]).
中国|0|广东省|广州市|电信
io:format("~ts~n", [xdb:search(<<"1.0.8.0">>)]).
中国|0|广东省|广州市|电信
4> io:format("~ts~n", [xdb:search({1,0,8,0})]).
中国|0|广东省|广州市|电信
6> io:format("~ts~n", [xdb:search(16779264)]).
中国|0|广东省|广州市|电信
``` ```
### 使用方法 ### 使用方法
...@@ -40,7 +58,7 @@ application:ensure_started(ip2region), ...@@ -40,7 +58,7 @@ application:ensure_started(ip2region),
...... ......
``` ```
* 调用ip2region:search/1接口查询IP信息 * 调用xdb:search/1接口查询IP信息
``` ```
...... ......
...@@ -57,18 +75,30 @@ $ rebar3 eunit ...@@ -57,18 +75,30 @@ $ rebar3 eunit
===> Analyzing applications... ===> Analyzing applications...
===> Compiling ip2region ===> Compiling ip2region
===> Performing EUnit tests... ===> Performing EUnit tests...
=INFO REPORT==== 13-Jan-2023::21:26:15.137021 === =INFO REPORT==== 17-Jan-2023::11:52:59.920155 ===
XdbFile:/home/admin/erl-workspace/ip2region/binding/erlang/_build/test/lib/ip2region/priv/ip2region.xdb XdbFile:/home/admin/erl-workspace/ip2region/binding/erlang/_build/test/lib/ip2region/priv/ip2region.xdb
...
Finished in 0.085 seconds ....
3 tests, 0 failures Finished in 0.074 seconds
4 tests, 0 failures
``` ```
### 基准测试 ### 基准测试
``` ```
$ cd benchmarks/ $ cd benchmarks/
$ sh ip2region-benchmark.sh $ sh xdb-benchmark.sh
===> Verifying dependencies...
===> Analyzing applications...
===> Compiling ip2region
Erlang/OTP 24 [erts-12.3.2.2] [source] [64-bit] [smp:2:2] [ds:2:2:10] [async-threads:1] [jit]
Eshell V12.3.2.2 (abort with ^G)
1> =INFO REPORT==== 17-Jan-2023::11:37:35.631095 ===
XdbFile:/home/admin/erl-workspace/ip2region/binding/erlang/_build/default/lib/ip2region/priv/ip2region.xdb
===> Booted ip2region
===> Evaluating: "xdb_benchmark:main(\"../../data/ip.merge.txt\"), init:stop()."
CPU info: CPU info:
model name : AMD EPYC 7K62 48-Core Processor model name : AMD EPYC 7K62 48-Core Processor
cache size : 512 KB cache size : 512 KB
...@@ -78,21 +108,21 @@ cores/threads : 2 ...@@ -78,21 +108,21 @@ cores/threads : 2
Erlang info: Erlang info:
system_version:Erlang/OTP 24 [erts-12.3.2.2] [source] [64-bit] [smp:2:2] [ds:2:2:10] [async-threads:1] [jit] system_version:Erlang/OTP 24 [erts-12.3.2.2] [source] [64-bit] [smp:2:2] [ds:2:2:10] [async-threads:1] [jit]
load test data use 2.724344s load test data use 4.835593s
start run benchmark tests start run benchmark tests
search from file: search from file:
ip count:683844, ip count:683844,
total time: 25.56304s, total time: 28.201699s,
search 26751.27840820184 times per second, search 24248.326315375536 times per second,
use 37.381391077497206 micro second per search use 41.23995969841075 micro second per search
search from cache: search from cache:
ip count:683844, ip count:683844,
total time: 0.670307s, total time: 0.671801s,
search 1020195.2239794602 times per second, search 1017926.4395259906 times per second,
use 0.9802045495756342 micro second per search use 0.9823892583688677 micro second per search
benchmark test finish benchmark test finish
......
#!/bin/bash
awk -v FS='|' '{print $1}' ../../../data/ip.merge.txt > test_data.txt
cd ..
rebar3 shell --eval="ip2region_benchmark:main(\"./benchmarks/test_data.txt\"), init:stop()."
此差异已折叠。
#!/bin/bash
cd ..
rebar3 shell --eval="xdb_benchmark:main(\"../../data/ip.merge.txt\"), init:stop()."
%%%------------------------------------------------------------------- %%%-------------------------------------------------------------------
%% @doc ip2region public API %% Copyright 2022 The Ip2Region Authors. All rights reserved.
%% Use of this source code is governed by a Apache2.0-style
%% license that can be found in the LICENSE file.
%%
%% @doc
%% @end %% @end
%%%------------------------------------------------------------------- %%%-------------------------------------------------------------------
......
%%%------------------------------------------------------------------- %%%-------------------------------------------------------------------
%% Copyright 2022 The Ip2Region Authors. All rights reserved.
%% Use of this source code is governed by a Apache2.0-style
%% license that can be found in the LICENSE file.
%%
%% @doc ip2region top level supervisor. %% @doc ip2region top level supervisor.
%% @end %% @end
%%%------------------------------------------------------------------- %%%-------------------------------------------------------------------
......
%%%-------------------------------------------------------------------
%% Copyright 2022 The Ip2Region Authors. All rights reserved.
%% Use of this source code is governed by a Apache2.0-style
%% license that can be found in the LICENSE file.
%%
%% @doc
%% ip2region utils
%% @end
%%%-------------------------------------------------------------------
-module(ip2region_util). -module(ip2region_util).
-export([ipv4_to_n/1]). -export([ipv4_to_n/1]).
......
%%%=============================================================== %%%-------------------------------------------------------------------
%%% @author leihua <leihua918@sina.com> %% Copyright 2022 The Ip2Region Authors. All rights reserved.
%%% @doc %% Use of this source code is governed by a Apache2.0-style
%%% ip2region工作进程 %% license that can be found in the LICENSE file.
%%% Created: 2023-1-13 16:53 %%
%%% @end %% @doc
%%%=============================================================== %% ip2region xdb client worker
%% @end
%%%-------------------------------------------------------------------
-module(ip2region_worker). -module(ip2region_worker).
-behaviour(gen_server). -behaviour(gen_server).
-include("ip2region.hrl"). -include("ip2region.hrl").
...@@ -37,6 +39,7 @@ search(Pid, Ip) -> ...@@ -37,6 +39,7 @@ search(Pid, Ip) ->
%% gen_server callbacks %% gen_server callbacks
%% ========================================= %% =========================================
init(_Args) -> init(_Args) ->
process_flag(trap_exit, true),
AppName = AppName =
case application:get_application() of case application:get_application() of
{ok, AName} -> AName; {ok, AName} -> AName;
...@@ -159,14 +162,7 @@ search_ip(IoDevice, IntIp, SPtr, EPtr, Low, High) when Low =< High -> ...@@ -159,14 +162,7 @@ search_ip(IoDevice, IntIp, SPtr, EPtr, Low, High) when Low =< High ->
search_ip(IoDevice, IntIp, SPtr, EPtr, Middle + 1, High); search_ip(IoDevice, IntIp, SPtr, EPtr, Middle + 1, High);
true -> true ->
{ok, DataBin} = read_file(IoDevice, DataPtr, DataLen), {ok, DataBin} = read_file(IoDevice, DataPtr, DataLen),
[Country, Region, Province, City, ISP] = string:tokens(binary_to_list(DataBin), "|"), unicode:characters_to_nfc_list(DataBin)
#{
country => ?IF(Country == "0", <<>>, list_to_binary(Country)),
region => ?IF(Region == "0", <<>>, list_to_binary(Region)),
province => ?IF(Province == "0", <<>>, list_to_binary(Province)),
city => ?IF(City == "0", <<>>, list_to_binary(City)),
isp => ?IF(ISP == "0", <<>>, list_to_binary(ISP))
}
end; end;
search_ip(_IoDevice, _IntIp, _SPtr, _EPtr, _Low, _High) -> search_ip(_IoDevice, _IntIp, _SPtr, _EPtr, _Low, _High) ->
{error, unknown}. {error, unknown}.
......
%%%=============================================================== %%%-------------------------------------------------------------------
%%% @author leihua <leihua918@sina.com> %% Copyright 2022 The Ip2Region Authors. All rights reserved.
%%% @doc %% Use of this source code is governed by a Apache2.0-style
%%% ip2region xdb 查询客户端 %% license that can be found in the LICENSE file.
%%% Created: 2023-1-13 16:53 %%
%%% @end %% @doc
%%%=============================================================== %% ip2region xdb client search api
-module(ip2region). %% @end
%%%-------------------------------------------------------------------
-module(xdb).
-include("ip2region.hrl"). -include("ip2region.hrl").
-export([search/1]). -export([search/1]).
-spec search(Ip :: tuple() | list() | binary()) -> Result :: {error, Reason::atom()} | map(). -spec search(Ip :: tuple() | list() | binary()) -> Result :: binary | {error, Reason::atom()}.
search(Ip) -> search(Ip) when is_integer(Ip); is_list(Ip); is_tuple(Ip); is_binary(Ip) ->
case ip2region_util:ipv4_to_n(Ip) of case ip2region_util:ipv4_to_n(Ip) of
IntIp when is_integer(IntIp) -> IntIp when is_integer(IntIp) ->
case ets:lookup(?IP2REGION_CACHE, IntIp) of case ets:lookup(?IP2REGION_CACHE, IntIp) of
......
%%%=============================================================== %%%-------------------------------------------------------------------
%%% @author leihua <leihua918@sina.com> %% Copyright 2022 The Ip2Region Authors. All rights reserved.
%%% @doc %% Use of this source code is governed by a Apache2.0-style
%%% ip2region性能基准测试 %% license that can be found in the LICENSE file.
%%% Created: 2023-1-13 17:46 %%
%%% @end %% @doc
%%%=============================================================== %% ip2region xdb client benchmark test
-module(ip2region_benchmark). %% @end
%%%-------------------------------------------------------------------
-module(xdb_benchmark).
-export([main/1]). -export([main/1]).
main(DataFile) -> main(DataFile) ->
...@@ -37,7 +39,12 @@ load_test_data(DataFile) -> ...@@ -37,7 +39,12 @@ load_test_data(DataFile) ->
load_test_data(Fd, IpList) -> load_test_data(Fd, IpList) ->
case file:read_line(Fd) of case file:read_line(Fd) of
{ok, Ip} -> {ok, Ip} ->
load_test_data(Fd, [string:trim(Ip)| IpList]); case string:tokens(unicode:characters_to_list(Ip), "|") of
[SIp | _Tail] ->
load_test_data(Fd, [string:trim(SIp)| IpList]);
_ ->
load_test_data(Fd, IpList)
end;
_ -> _ ->
file:close(Fd), file:close(Fd),
IpList IpList
...@@ -63,6 +70,6 @@ run_test(IpList) -> ...@@ -63,6 +70,6 @@ run_test(IpList) ->
run_test_aux([]) -> ok; run_test_aux([]) -> ok;
run_test_aux([Ip | Tail]) -> run_test_aux([Ip | Tail]) ->
#{} = ip2region:search(Ip), xdb:search(Ip),
run_test_aux(Tail). run_test_aux(Tail).
-module(ip2region_test). -module(xdb_test).
-include_lib("eunit/include/eunit.hrl"). -include_lib("eunit/include/eunit.hrl").
search_test_() -> search_test_() ->
application:ensure_started(ip2region), application:ensure_started(ip2region),
A = #{ A = "中国|0|广东省|广州市|电信",
city => <<"广州市"/utf8>>, Region0 = xdb:search("1.0.8.0"),
country => <<"中国"/utf8>>, Region1 = xdb:search(<<"1.0.8.0">>),
isp => <<"电信"/utf8>>, Region2 = xdb:search({1,0,8,0}),
province => <<"广东省"/utf8>>, Region3 = xdb:search("xxx.0.8.0"),
region => <<>>
},
Region1 = ip2region:search("1.0.8.0"),
Region2 = ip2region:search({1,0,8,0}),
Region3 = ip2region:search("xxx.0.8.0"),
[ [
?_assert(A =:= Region0),
?_assert(A =:= Region1), ?_assert(A =:= Region1),
?_assert(A =:= Region2), ?_assert(A =:= Region2),
?_assert({error, bad_ip_format} =:= Region3) ?_assert({error, bad_ip_format} =:= Region3)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册