mirror of
https://github.com/lionsoul2014/ip2region.git
synced 2025-12-08 19:25:22 +00:00
1.查询接口模块名为xdb;2.查询接口返回字符串;3.增加 apache 授权信息;4.调整基准测试数据来源
This commit is contained in:
parent
0a4d16b434
commit
f053e97b23
@ -1,5 +1,18 @@
|
||||
# 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
|
||||
$ rebar3 shell
|
||||
|
||||
```
|
||||
在erlang节点中执行以下指令查询Ip地址信息:
|
||||
在erlang shell中调用xdb:search/1接口查询Ip地址信息, 该接口支持以list格式字符串、bianry格式字符串、tuple和整数表示的IP地址,如下:
|
||||
```
|
||||
1> ip2region:search("1.0.8.0").
|
||||
#{city => <<229,185,191,229,183,158,229,184,130>>,
|
||||
country => <<228,184,173,229,155,189>>,
|
||||
isp => <<231,148,181,228,191,161>>,
|
||||
province => <<229,185,191,228,184,156,231,156,129>>,
|
||||
region => <<>>}
|
||||
1> xdb:search("1.0.8.0").
|
||||
[20013,22269,124,48,124,24191,19996,30465,124,24191,24030,
|
||||
24066,124,30005,20449]
|
||||
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),
|
||||
......
|
||||
```
|
||||
|
||||
* 调用ip2region:search/1接口查询IP信息
|
||||
* 调用xdb:search/1接口查询IP信息
|
||||
```
|
||||
......
|
||||
|
||||
@ -57,18 +75,30 @@ $ rebar3 eunit
|
||||
===> Analyzing applications...
|
||||
===> Compiling ip2region
|
||||
===> 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
|
||||
...
|
||||
Finished in 0.085 seconds
|
||||
3 tests, 0 failures
|
||||
|
||||
....
|
||||
Finished in 0.074 seconds
|
||||
4 tests, 0 failures
|
||||
|
||||
```
|
||||
|
||||
### 基准测试
|
||||
```
|
||||
$ 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:
|
||||
model name : AMD EPYC 7K62 48-Core Processor
|
||||
cache size : 512 KB
|
||||
@ -78,21 +108,21 @@ cores/threads : 2
|
||||
|
||||
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]
|
||||
load test data use 2.724344s
|
||||
load test data use 4.835593s
|
||||
|
||||
start run benchmark tests
|
||||
|
||||
search from file:
|
||||
ip count:683844,
|
||||
total time: 25.56304s,
|
||||
search 26751.27840820184 times per second,
|
||||
use 37.381391077497206 micro second per search
|
||||
total time: 28.201699s,
|
||||
search 24248.326315375536 times per second,
|
||||
use 41.23995969841075 micro second per search
|
||||
|
||||
search from cache:
|
||||
ip count:683844,
|
||||
total time: 0.670307s,
|
||||
search 1020195.2239794602 times per second,
|
||||
use 0.9802045495756342 micro second per search
|
||||
total time: 0.671801s,
|
||||
search 1017926.4395259906 times per second,
|
||||
use 0.9823892583688677 micro second per search
|
||||
|
||||
benchmark test finish
|
||||
|
||||
|
||||
@ -1,7 +0,0 @@
|
||||
#!/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()."
|
||||
File diff suppressed because it is too large
Load Diff
5
binding/erlang/benchmarks/xdb-benchmark.sh
Executable file
5
binding/erlang/benchmarks/xdb-benchmark.sh
Executable file
@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
cd ..
|
||||
|
||||
rebar3 shell --eval="xdb_benchmark:main(\"../../data/ip.merge.txt\"), init:stop()."
|
||||
@ -1,30 +0,0 @@
|
||||
|
||||
%%%===============================================================
|
||||
%%% @author leihua <leihua918@sina.com>
|
||||
%%% @doc
|
||||
%%% ip2region xdb 查询客户端
|
||||
%%% Created: 2023-1-13 16:53
|
||||
%%% @end
|
||||
%%%===============================================================
|
||||
-module(ip2region).
|
||||
-include("ip2region.hrl").
|
||||
|
||||
-export([search/1]).
|
||||
|
||||
-spec search(Ip :: tuple() | list() | binary()) -> Result :: {error, Reason::atom()} | map().
|
||||
search(Ip) ->
|
||||
case ip2region_util:ipv4_to_n(Ip) of
|
||||
IntIp when is_integer(IntIp) ->
|
||||
case ets:lookup(?IP2REGION_CACHE, IntIp) of
|
||||
[{_IntIp, Region}] -> Region;
|
||||
_ ->
|
||||
Worker = poolboy:checkout(?IP2REGION_POOL, true, infinity),
|
||||
try
|
||||
ip2region_worker:search(Worker, IntIp)
|
||||
after
|
||||
poolboy:checkin(?IP2REGION_POOL, Worker)
|
||||
end
|
||||
end;
|
||||
Ret ->
|
||||
Ret
|
||||
end.
|
||||
@ -1,5 +1,9 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
%% @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
|
||||
%%%-------------------------------------------------------------------
|
||||
|
||||
|
||||
@ -1,4 +1,8 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
%% 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.
|
||||
%% @end
|
||||
%%%-------------------------------------------------------------------
|
||||
|
||||
@ -1,3 +1,12 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
%% 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).
|
||||
-export([ipv4_to_n/1]).
|
||||
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
%%%===============================================================
|
||||
%%% @author leihua <leihua918@sina.com>
|
||||
%%% @doc
|
||||
%%% ip2region工作进程
|
||||
%%% Created: 2023-1-13 16:53
|
||||
%%% @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 xdb client worker
|
||||
%% @end
|
||||
%%%-------------------------------------------------------------------
|
||||
-module(ip2region_worker).
|
||||
-behaviour(gen_server).
|
||||
-include("ip2region.hrl").
|
||||
@ -37,6 +39,7 @@ search(Pid, Ip) ->
|
||||
%% gen_server callbacks
|
||||
%% =========================================
|
||||
init(_Args) ->
|
||||
process_flag(trap_exit, true),
|
||||
AppName =
|
||||
case application:get_application() of
|
||||
{ok, AName} -> AName;
|
||||
@ -159,14 +162,7 @@ search_ip(IoDevice, IntIp, SPtr, EPtr, Low, High) when Low =< High ->
|
||||
search_ip(IoDevice, IntIp, SPtr, EPtr, Middle + 1, High);
|
||||
true ->
|
||||
{ok, DataBin} = read_file(IoDevice, DataPtr, DataLen),
|
||||
[Country, Region, Province, City, ISP] = string:tokens(binary_to_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))
|
||||
}
|
||||
unicode:characters_to_nfc_list(DataBin)
|
||||
end;
|
||||
search_ip(_IoDevice, _IntIp, _SPtr, _EPtr, _Low, _High) ->
|
||||
{error, unknown}.
|
||||
|
||||
32
binding/erlang/src/xdb.erl
Normal file
32
binding/erlang/src/xdb.erl
Normal file
@ -0,0 +1,32 @@
|
||||
|
||||
%%%-------------------------------------------------------------------
|
||||
%% 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 xdb client search api
|
||||
%% @end
|
||||
%%%-------------------------------------------------------------------
|
||||
-module(xdb).
|
||||
-include("ip2region.hrl").
|
||||
|
||||
-export([search/1]).
|
||||
|
||||
-spec search(Ip :: tuple() | list() | binary()) -> Result :: binary | {error, Reason::atom()}.
|
||||
search(Ip) when is_integer(Ip); is_list(Ip); is_tuple(Ip); is_binary(Ip) ->
|
||||
case ip2region_util:ipv4_to_n(Ip) of
|
||||
IntIp when is_integer(IntIp) ->
|
||||
case ets:lookup(?IP2REGION_CACHE, IntIp) of
|
||||
[{_IntIp, Region}] -> Region;
|
||||
_ ->
|
||||
Worker = poolboy:checkout(?IP2REGION_POOL, true, infinity),
|
||||
try
|
||||
ip2region_worker:search(Worker, IntIp)
|
||||
after
|
||||
poolboy:checkin(?IP2REGION_POOL, Worker)
|
||||
end
|
||||
end;
|
||||
Ret ->
|
||||
Ret
|
||||
end.
|
||||
@ -1,11 +1,13 @@
|
||||
%%%===============================================================
|
||||
%%% @author leihua <leihua918@sina.com>
|
||||
%%% @doc
|
||||
%%% ip2region性能基准测试
|
||||
%%% Created: 2023-1-13 17:46
|
||||
%%% @end
|
||||
%%%===============================================================
|
||||
-module(ip2region_benchmark).
|
||||
%%%-------------------------------------------------------------------
|
||||
%% 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 xdb client benchmark test
|
||||
%% @end
|
||||
%%%-------------------------------------------------------------------
|
||||
-module(xdb_benchmark).
|
||||
-export([main/1]).
|
||||
|
||||
main(DataFile) ->
|
||||
@ -37,7 +39,12 @@ load_test_data(DataFile) ->
|
||||
load_test_data(Fd, IpList) ->
|
||||
case file:read_line(Fd) of
|
||||
{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),
|
||||
IpList
|
||||
@ -63,6 +70,6 @@ run_test(IpList) ->
|
||||
|
||||
run_test_aux([]) -> ok;
|
||||
run_test_aux([Ip | Tail]) ->
|
||||
#{} = ip2region:search(Ip),
|
||||
xdb:search(Ip),
|
||||
run_test_aux(Tail).
|
||||
|
||||
@ -1,22 +0,0 @@
|
||||
-module(ip2region_test).
|
||||
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
|
||||
search_test_() ->
|
||||
application:ensure_started(ip2region),
|
||||
A = #{
|
||||
city => <<"广州市"/utf8>>,
|
||||
country => <<"中国"/utf8>>,
|
||||
isp => <<"电信"/utf8>>,
|
||||
province => <<"广东省"/utf8>>,
|
||||
region => <<>>
|
||||
},
|
||||
Region1 = ip2region:search("1.0.8.0"),
|
||||
Region2 = ip2region:search({1,0,8,0}),
|
||||
Region3 = ip2region:search("xxx.0.8.0"),
|
||||
[
|
||||
?_assert(A =:= Region1),
|
||||
?_assert(A =:= Region2),
|
||||
?_assert({error, bad_ip_format} =:= Region3)
|
||||
|
||||
].
|
||||
18
binding/erlang/test/xdb_test.erl
Normal file
18
binding/erlang/test/xdb_test.erl
Normal file
@ -0,0 +1,18 @@
|
||||
-module(xdb_test).
|
||||
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
|
||||
search_test_() ->
|
||||
application:ensure_started(ip2region),
|
||||
A = "中国|0|广东省|广州市|电信",
|
||||
Region0 = xdb:search("1.0.8.0"),
|
||||
Region1 = xdb:search(<<"1.0.8.0">>),
|
||||
Region2 = xdb:search({1,0,8,0}),
|
||||
Region3 = xdb:search("xxx.0.8.0"),
|
||||
[
|
||||
?_assert(A =:= Region0),
|
||||
?_assert(A =:= Region1),
|
||||
?_assert(A =:= Region2),
|
||||
?_assert({error, bad_ip_format} =:= Region3)
|
||||
|
||||
].
|
||||
Loading…
x
Reference in New Issue
Block a user