You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
377 lines
12 KiB
377 lines
12 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using System.Net;
|
|
|
|
using Sog.ClusterCfg;
|
|
|
|
namespace Sog
|
|
{
|
|
public class ClusterApp
|
|
{
|
|
public string idc { get; private set; }
|
|
public string BussinessName { get; private set; }
|
|
public string Name { get; private set; }
|
|
|
|
public uint ServerID { get; private set; }
|
|
public string ServerIDStr { get; private set; }
|
|
|
|
//外网
|
|
public IPEndPoint ExternalIPPort { get; private set; }
|
|
//内网
|
|
public IPEndPoint InnerIPPort { get; private set; }
|
|
|
|
public int listenAnyIP { get; private set; }
|
|
|
|
//是否是主动连还是被动连
|
|
public bool IsClientCluster { get; private set; }
|
|
|
|
public int BufferSize { get; private set; }
|
|
|
|
public string Host { get; private set; }
|
|
|
|
public string CfgPath { get; private set; }
|
|
public string Cfgfile { get; private set; }
|
|
|
|
//自定义参数key,value列表
|
|
public Dictionary<string,string> ParamsMap { get; private set; }
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="config"></param>
|
|
/// <param name="instOff">多个inst的时候inst的偏移</param>
|
|
public ClusterApp()
|
|
{
|
|
ParamsMap = new Dictionary<string, string>();
|
|
}
|
|
|
|
|
|
//根据配置文件解析我自己的配置和我相关有连接的app配置
|
|
public static void ParseWithMyAppId(ClusterConfig config, Dictionary<uint, ClusterApp> appMap, uint serverId)
|
|
{
|
|
int worldid = (int)ServerIDUtils.GetWorldID(serverId);
|
|
int apptype = (int)ServerIDUtils.GetServerType(serverId);
|
|
int instid = (int)ServerIDUtils.GetInstanceID(serverId);
|
|
|
|
string appname = GetAppNameByAppType(config, worldid, apptype);
|
|
string groupname = null;
|
|
|
|
BusinessConfig myBusiness = null;
|
|
HostConfig myHost = null;
|
|
GroupProcConfig myProc = null;
|
|
|
|
GetMyHost(config, out myBusiness, out myHost);
|
|
|
|
//添加自己
|
|
foreach (var group in myHost.groups)
|
|
{
|
|
GroupDeplayConfig groupconfig = GetGroupByName(config, group.groupname);
|
|
foreach(var proc in groupconfig.procs)
|
|
{
|
|
if(proc.app == appname && proc.instid == instid)
|
|
{
|
|
myProc = proc;
|
|
groupname = groupconfig.groupname;
|
|
|
|
ClusterApp app = MakeClusterAppInfo(config, myBusiness, myHost, groupconfig, myProc, false);
|
|
|
|
appMap.Add(app.ServerID, app);
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//找到部署在当前host上的app group, 将group中与当前app有管道关系的加入appDict
|
|
foreach (var host in myBusiness.hosts)
|
|
{
|
|
foreach (var group in host.groups)
|
|
{
|
|
GroupDeplayConfig groupconfig = GetGroupByName(config, group.groupname);
|
|
foreach (var proc in groupconfig.procs)
|
|
{
|
|
if (proc.app == appname && proc.instid == instid)
|
|
{
|
|
}
|
|
else
|
|
{
|
|
//有管道关系
|
|
int channelRelation = GetChannelRelation(config, appname, worldid, instid, host, proc);
|
|
if (channelRelation != 0)
|
|
{
|
|
ClusterApp app = MakeClusterAppInfo(config, myBusiness, host, groupconfig, proc, channelRelation == 2);
|
|
|
|
appMap.Add(app.ServerID, app);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
public static string GetAppNameByAppType(ClusterConfig config, int worldid, int apptype)
|
|
{
|
|
if(worldid == 0)
|
|
{
|
|
foreach(var app in config.cluster_layer_apps)
|
|
{
|
|
if(app.apptype == apptype)
|
|
{
|
|
return app.name;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
foreach(var app in config.world_layer_apps)
|
|
{
|
|
if (app.apptype == apptype)
|
|
{
|
|
return app.name;
|
|
}
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public static int GetAppTypeByName(ClusterConfig config, string appName, out bool isworldlayer)
|
|
{
|
|
isworldlayer = false;
|
|
|
|
foreach (var app in config.cluster_layer_apps)
|
|
{
|
|
if (app.name == appName)
|
|
{
|
|
return app.apptype;
|
|
}
|
|
}
|
|
|
|
foreach (var app in config.world_layer_apps)
|
|
{
|
|
if (app.name == appName)
|
|
{
|
|
isworldlayer = true;
|
|
return app.apptype;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
public static void GetMyHost(ClusterConfig config,
|
|
out BusinessConfig business, out HostConfig host)
|
|
{
|
|
business = null;
|
|
host = null;
|
|
|
|
foreach (var tmpbusiness in config.bussiness)
|
|
{
|
|
foreach (var tmphost in tmpbusiness.hosts)
|
|
{
|
|
bool isMyHost = NetUtils.IsThisMachineAddress(tmphost.hostname);
|
|
if (isMyHost)
|
|
{
|
|
business = tmpbusiness;
|
|
host = tmphost;
|
|
return;
|
|
}
|
|
|
|
isMyHost = NetUtils.IsThisMachineAddress(tmphost.innerip);
|
|
if(isMyHost)
|
|
{
|
|
business = tmpbusiness;
|
|
host = tmphost;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static GroupDeplayConfig GetGroupByName(ClusterConfig config, string groupname)
|
|
{
|
|
foreach(var group in config.groupdeploy)
|
|
{
|
|
if(group.groupname == groupname)
|
|
{
|
|
return group;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public static int GetChannelRelation(ClusterConfig config, string myApp, int myWorldId, int myInstId, HostConfig otherHost,GroupProcConfig otherProc)
|
|
{
|
|
string otherApp = otherProc.app;
|
|
int otherInstId = otherProc.instid;
|
|
|
|
bool isworldlayer;
|
|
int apptype = GetAppTypeByName(config, otherProc.app, out isworldlayer);
|
|
|
|
int otherWorldId = isworldlayer ? otherHost.worldid : 0;
|
|
|
|
//如果是world层的进程,缺省不支持跨world连接
|
|
if (myWorldId != 0 && otherWorldId != 0 && myWorldId != otherWorldId)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
foreach(var channel in config.channels)
|
|
{
|
|
//我连他
|
|
if(myApp == channel.app1 && otherApp == channel.app2)
|
|
{
|
|
// 同名服务, instId在前的主动连接所有后面的
|
|
if (myApp == otherApp)
|
|
{
|
|
return myInstId < otherInstId ? 1 : 2;
|
|
}
|
|
|
|
// 0 表示网状连接, 1 表示instId相同的app进行一对一连接
|
|
if (channel.type == 1)
|
|
{
|
|
return myInstId == otherInstId ? 1 : 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
//他连我
|
|
if (myApp == channel.app2 && otherApp == channel.app1)
|
|
{
|
|
// 同名服务, instId在前的主动连接所有后面的
|
|
if (myApp == otherApp)
|
|
{
|
|
return myInstId < otherInstId ? 1 : 2;
|
|
}
|
|
|
|
// 0 表示网状连接, 1 表示instId相同的app进行一对一连接
|
|
if (channel.type == 1)
|
|
{
|
|
return myInstId == otherInstId ? 2 : 0;
|
|
}
|
|
|
|
return 2;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
public static ClusterApp MakeClusterAppInfo(ClusterConfig config,
|
|
BusinessConfig business, HostConfig host, GroupDeplayConfig group, GroupProcConfig proc, bool isClientCluster)
|
|
{
|
|
ClusterApp app = new ClusterApp();
|
|
|
|
app.idc = host.idc;
|
|
app.BussinessName = business.businessname;
|
|
app.Host = host.hostname;
|
|
app.CfgPath = host.cfgpath + "/" + proc.app;
|
|
app.Cfgfile = host.cfgpath + "/" + proc.app + "/" + proc.cfg;
|
|
|
|
//参数化的变量处理
|
|
ParseParams(business.param, app.ParamsMap);
|
|
ParseParams(host.param, app.ParamsMap);
|
|
ParseParams(proc.param, app.ParamsMap);
|
|
|
|
if (string.IsNullOrEmpty(host.externalip) == false)
|
|
{
|
|
IPAddress addressExternal = IPAddress.Parse(host.externalip);
|
|
app.ExternalIPPort = new IPEndPoint(addressExternal, proc.clusterport);
|
|
}
|
|
|
|
IPAddress address = IPAddress.Parse(host.innerip);
|
|
app.InnerIPPort = new IPEndPoint(address, proc.clusterport);
|
|
app.listenAnyIP = host.listenanyip;
|
|
|
|
app.BufferSize = 1024000;
|
|
app.IsClientCluster = isClientCluster;
|
|
|
|
bool isworldlayer;
|
|
int apptype = GetAppTypeByName(config, proc.app, out isworldlayer);
|
|
|
|
app.ServerID = ServerIDUtils.MakeServerID(isworldlayer ? host.worldid : 0, apptype, proc.instid);
|
|
app.ServerIDStr = ServerIDUtils.IDToString(app.ServerID);
|
|
app.Name = proc.app + proc.instid;
|
|
|
|
return app;
|
|
}
|
|
|
|
public static void ParseParams(string param, Dictionary<string, string> ParamsMap)
|
|
{
|
|
if(string.IsNullOrEmpty(param))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if(param.Length == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
string[] splits = param.Split(',');
|
|
|
|
foreach(string split in splits)
|
|
{
|
|
if(string.IsNullOrEmpty(split))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
string[] keyvalue = split.Split('=');
|
|
if(keyvalue.Length != 2)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
string key = keyvalue[0];
|
|
string value = keyvalue[1];
|
|
|
|
if(string.IsNullOrEmpty(key))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if(value == null)
|
|
{
|
|
value = "";
|
|
}
|
|
|
|
key = key.Trim();
|
|
value = value.Trim();
|
|
|
|
if(key.Length == 0)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//添加
|
|
if(ParamsMap.ContainsKey(key) == false)
|
|
{
|
|
ParamsMap.Add(key, value);
|
|
}
|
|
else//更新
|
|
{
|
|
ParamsMap[key] = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
public static IPEndPoint GetRemoteIpEndPoint(ClusterApp thisApp, ClusterApp remoteApp)
|
|
{
|
|
IPEndPoint remoteIPEndPoint = remoteApp.InnerIPPort;
|
|
//不是同一个idc并且远程机器可以接受外网连接
|
|
if (thisApp.idc != remoteApp.idc && remoteApp.listenAnyIP == 1)
|
|
{
|
|
remoteIPEndPoint = remoteApp.ExternalIPPort;
|
|
}
|
|
return remoteIPEndPoint;
|
|
}
|
|
|
|
}
|
|
}
|
|
|