金庆的专栏

  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  423 随笔 :: 0 文章 :: 454 评论 :: 0 Trackbacks
区服节点互连
(金庆的专栏)

【上海龙图招聘】

所有Erlang服务器节点加入同一集群,使用相同的cookie。
使用BIF erlang:set_cookie(node(), C)把本地节点的cookie设置为原子C。

1个或多个节点配置为主节点(主服务器)。
主节点不必全部启动,但要求至少启动1个。
主节点配置可热更新即时生效。
主节点启动后,主动连接所有未连接的主节点,每隔5s尝试连接。
其他节点,如新开区服,仅需连接主节点。
所有主节点和其他节点最终全互连。

仅需配置主服务器内网地址,利用net_adm:world_list([Host])连接所有节点。
客户端仅需配置数个主服务器的地址,连上某个主服后即可查询所有服务器的地址与负载。
客户端一般会记录后最连接的服务器,用于角色重登,同样也可查询服务器列表。

ping_main_hosts() ->
    MainHosts = config_main_hosts:get(),
    Nodes = net_adm:world_list(MainHosts),
    lager:debug("Ping main hosts: ~p. Result nodes: ~p", [MainHosts, Nodes]),
    ok.

18:34:45.023 [debug] Ping main hosts: ['127.0.0.1']. Result nodes: []
18:34:50.029 [debug] Ping main hosts: ['127.0.0.1']. Result nodes: []
Reloading config_main_hosts ... ok.
18:34:55.272 [debug] Ping main hosts: ['192.168.8.9','127.0.0.1']. Result nodes: ['s3@192.168.8.9']
18:35:00.057 [debug] Ping main hosts: ['192.168.8.9','127.0.0.1']. Result nodes: ['s3@192.168.8.9']

cluster_svr 处理集群互连。

%%%-------------------------------------------------------------------
%%% @author jinqing
%%% @copyright (C) 2015, <COMPANY>
%%% @doc 集群互连服务器。
%%%      处理集群互连。广播自身节点状态,接收其他节点状态。
%%% @end
%%% Created : 23. 四月 2015 12:12
%%%-------------------------------------------------------------------
-module(cluster_svr).
-author("jinqing").

-behaviour(gen_server).

...
-type state() :: #{nodes => [node()]}.
-type server_info() :: #{host_cfg => config_gateway:host_cfg(),
                         current_load => integer()}.
-export_type([server_info/0]).
...
init([]) ->
    init_ets(),
    init_timer(),
    {ok, #{}}.

...
handle_info(timer_ping, State) ->
    NewState = timer_ping(State),
    {noreply, NewState};

handle_info(timer_bcast_info, State) ->
    timer_bcast_info(),
    {noreply, State};

handle_info({server_info, ServerId, ServerInfo}, State)
    when is_integer(ServerId), is_map(ServerInfo) ->
    lager:debug("~p Server~p info: ~p", [self(), ServerId, ServerInfo]),
    ets:insert(ets_server, {ServerId, ServerInfo}),
    {noreply, State};

...
init_timer() ->
    % 启动时短时间内Ping多次,接着每隔10s定时Ping.
    {ok, _} = timer:send_after(200, self(), timer_ping),
    {ok, _} = timer:send_after(1000, self(), timer_ping),
    {ok, _} = timer:send_interval(10000, self(), timer_ping),

    {ok, _} = timer:send_after(2000, self(), timer_bcast_info),
    {ok, _} = timer:send_after(5000, self(), timer_bcast_info),
    {ok, _} = timer:send_interval(31000, self(), timer_bcast_info),
    ok.

init_ets() ->
    ets:new(ets_server, [named_table]),  % 区服列表
    ok.

-spec timer_ping(State :: state()) -> state().
timer_ping(State) ->
    % lager:debug("timer_ping"),
    spawn(cluster_ping, ping_main_hosts, []),
    PrevNodes = maps:get(nodes, State, []),
    Nodes = nodes(),
    case (Nodes =:= PrevNodes) of
        true -> State;
        _ ->
            % 如果有节点更新,就打印节点列表。
            AllNodes = [node() | Nodes],
            lager:info("All nodes: ~p", [AllNodes]),
            State#{nodes => Nodes}
    end.

timer_bcast_info() ->
    % lager:debug("timer_bcast_info"),
    ServerId = six_util:get_server_id(),
    ServerInfo = cluster_server_info:get(ServerId),
    rpc:abcast(nodes(), ?MODULE, {server_info, ServerId, ServerInfo}),
    ok.

【上海龙图招聘】
posted on 2015-05-11 10:37 金庆 阅读(502) 评论(0)  编辑 收藏 引用

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理