Пример #1
0
        /// <summary>
        /// 创建主方法
        /// </summary>
        /// <param name="path">dll 路径</param>
        /// <param name="outPutDir">输出proxy.cs 文件路径</param>
        /// <param name="template">模板</param>
        /// <param name="templateBody">模板主体</param>
        /// <param name="interfaceBody">接口主体</param>
        /// <returns>返回是否创建成功</returns>
        public bool Create(string path, string outPutDir, string template, string templateBody, string interfaceBody)
        {
            try
            {
                var asLoad = LoadAssembly(path);

                Type[]        types           = asLoad.GetTypes();
                string        assShortName    = AssemblyToolProxy.GetCurrentAppName(asLoad);
                StringBuilder body            = new StringBuilder();
                StringBuilder interfaceBodySb = new StringBuilder();
                body.AppendLine(string.Format("private const string serviceName=\"{0}\";", assShortName));
                body.AppendLine();

                // 加载所有继承了AppBase的类
                var useTypes = types.Where(t => RpcDistributer.isChildAppBase(t) && !t.IsAbstract).ToList();
                return(WriteFile(outPutDir, template, templateBody, interfaceBody, useTypes, body, interfaceBodySb, assShortName));
            }
            catch (ReflectionTypeLoadException rtlEx)
            {
                logger.LogError(rtlEx, $"无法加载程序集:{rtlEx.Message}");
                if (rtlEx.LoaderExceptions != null && rtlEx.LoaderExceptions.Length > 0)
                {
                    foreach (var lex in rtlEx.LoaderExceptions)
                    {
                        logger.LogError(lex, $"无法加载程序集:{lex.Message}");
                    }
                }
            }
            catch (TypeLoadException tlEx)
            {
                logger.LogError(tlEx, $"无法加载程序集: {tlEx.TypeName}");
            }
            catch (FileNotFoundException fNtEx)
            {
                logger.LogError(fNtEx, $"无法加载程序集: {fNtEx.FileName}");
            }

            return(false);
        }
Пример #2
0
        /// <summary>
        /// 注册服务
        /// </summary>
        /// <param name="server">服务配置</param>
        public void RpcServerRegister(SuperGMSServerConfig server)
        {
            try
            {
                distributer = new RpcDistributer(server);  // 这里会初始化serverSetting和zk连接以及其他配置

                // 注册zk登记自己(包括serverName,ip,port,pool)
                server.ServerName = distributer.ShortName; // 兼容集中配置
                if (server.PortList != null && server.PortList.ContainsKey(server.ServerName))
                {
                    server.Port = server.PortList[server.ServerName];
                    ServerSetting.UpdateRpcPort(server.Port);
                }

                bool IsExit = false;
                // 要先初始化系统相关组件之后才能注册Rpc端口,要不请·求上来了,还没有初始化其他的,会有问题
                // 去zk注册自己
                if (ServerSetting.ConfigCenter.ConfigType == ConfigType.Zookeeper)
                {
                    Task.Run(() =>
                    {
                        Random r = new Random();
                        // rpc注册socket是阻塞的,只能提前通过线程注册, 等待1s 再注册路由,这个过程中,如果rpc端口不成功,将会撤销资源退出,这个注册也就失败了,防止先注册路由,然后再rpc注册异常,导致路由瞬间抖动,造成瞬间无效广播;
                        Thread.Sleep(r.Next(1500, 2500));  // 随机等待在1s--2s之间吧,防止集群一瞬间同时重启,容易形成广播风暴,形成雪崩;
                        if (IsExit)
                        {
                            return;
                        }
                        ServerSetting.RegisterRouter(server.ServerName, server.Ip, server.Port,
                                                     ServerSetting.GetRpcServer().Enable, server.TimeOut);
                        logger.LogInformation($"\r\n服务名:{server.ServerName},开始监听Ip是:{server.Ip},端口是:{server.Port}\r\n*******************▄︻┻┳══━一zookeeper路由注册成功,系统启动成功!▄︻┻┳══━一*******************");
                    });
                }
                else
                {
                    Task.Run(() =>
                    {
                        Thread.Sleep(1500);
                        if (IsExit)
                        {
                            return;
                        }
                        logger.LogInformation($"\r\n服务名:{server.ServerName},开始监听Ip是:{server.Ip},端口是:{server.Port}\r\n*******************▄︻┻┳══━一启用本地配置,系统启动成功!▄︻┻┳══━一*******************");
                    });
                }
                ServerRegister(server); // 底层通讯和业务进行绑定
                // 只有socket才会阻塞
                if (server.ServerType == ServerType.Thrift || server.ServerType == ServerType.Grpc)
                {
                    IsExit = true; // 通知所有注册方,停止注册,系统要撤销所有资源了,防止其他异常,优雅一点点,不能太暴力
                    logger.LogWarning($"\r\n rpc端口监听异常退出:{server.ServerName}{server.Port}{server.AssemblyPath}" + "  \r\n time=" +
                                      DateTime.Now.ToString("yy-MM-dd HH:mm:ss:ffff"));

                    if (ServerSetting.ConfigCenter.ConfigType == ConfigType.Zookeeper)
                    {
                        ZookeeperManager.ClearRouter(server.ServerName, server.Ip);
                    }

                    // rpc监听是hold住当前线程的,因为底层吞掉异常了,跑到这里来就说明异常了,要彻底释放
                    // 让他等一下,把日志写完
                    System.Threading.Thread.Sleep(1000);

                    // 如果启动失败,一定要彻底清理退出,因为在线程中,只能这样,要不只是线程退出,主程序还运行
                    Environment.Exit(0);
                }
            }
            catch (Exception ex)
            {
                logger.LogCritical(ex, "\r\n Error 服务异常退出  " + DateTime.Now.ToString("yy-MM-dd HH:mm:ss:ffff"));

                // 让他等一下,把日志写完
                System.Threading.Thread.Sleep(1000);

                // 如果启动失败,一定要彻底清理退出,因为在线程中,只能这样,要不只是线程退出,主程序还运行
                Environment.Exit(0);
            }
        }