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

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

上级 32372fa8
# 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
......
#!/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
%%%-------------------------------------------------------------------
......
%%%-------------------------------------------------------------------
%% 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
%%%-------------------------------------------------------------------
......
%%%-------------------------------------------------------------------
%% 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]).
......
%%%===============================================================
%%% @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}.
......
%%%===============================================================
%%% @author leihua <leihua918@sina.com>
%%% @doc
%%% ip2region xdb 查询客户端
%%% Created: 2023-1-13 16:53
%%% @end
%%%===============================================================
-module(ip2region).
%%%-------------------------------------------------------------------
%% 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 :: {error, Reason::atom()} | map().
search(Ip) ->
-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
......
%%%===============================================================
%%% @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).
-module(ip2region_test).
-module(xdb_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"),
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)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册