• lms微服务框架介绍


    lms 框架简介

    Lms是一个旨在通过.net平台快速构建微服务开发的框架。具有稳定、安全、高性能、易扩展、使用方便的特点。lms内部通过dotnetty实现高性能的rpc通信,使用zookeeper作为服务注册中心。RPC通信支持随机轮询、哈希一致性、随机路由等负载均衡算法。

    您还可以很方便的与CAP或是MassTransit集成,使用事件总线进行内部通信。

    开源地址

    https://github.com/liuhll/lms

    该框架现在还正在开发过程中,如果您也认可该框架,您可以给个star,或是提交pr参与贡献,如果遇到问题,您也可以通过issues需求帮助。

    快速开始

    LMS框架集成与服务托管

    使用通用主机注册和托管LMS服务

    使用LMS框架非常简单,您只需要使用.net提供的通用主机注册LMS框架,同时指定启动的模块,在启动的模块中,通过DependsOn特性依赖必要的组件。

    通用主机注册LMS框架主要用于一般情况下对服务的托管,配置的token保证的集群通信的安全性,避免用户直接通过RPC端口访问集群内部,

    (1) 只有请求来源于网关,才被认为是合法的请求。集群外部无法通过rpc端口与主机直接通信。

    (2) 服务内部通信过程中,同一个集群只有配置的token一致, 通信才会被被认为是合法的。

    1. 注册LMS服务
        public class Program
        {
            public static async Task Main(string[] args)
            {
                await CreateHostBuilder(args).Build().RunAsync();
            }
    
            private static IHostBuilder CreateHostBuilder(string[] args)
            {
                return Host.CreateDefaultBuilder(args)
                        .RegisterLmsServices<NormModule>() //注册lms服务,并指定启动的模块
                    ;
    
            }
        }
    
    1. 指定启动模块
        [DependsOn(typeof(ZookeeperModule), 
          typeof(DotNettyTcpModule), 
          typeof(RpcProxyModule),
          typeof(MessagePackModule))]
        public class NormModule : LmsModule
        {
            
        }
    

    启动模块必须要继承LmsModule基类,通过DependsOn特性指定依赖的模块组件,一般的,您需要依赖服务注册中心组件(ZookeeperModule)、和通信框架组件(DotNettyTcpModule)、Rpc通信代理组件(RpcProxyModule),也可以指定编解码组件(MessagePackModule或是ProtoBufferModule),如果未指定编解码组件,则默认使用json作为rpc内部的通信编解码格式。同一个集群内部,必须要保证使用的编解码一致。

    在启动模块中,您也可以通过重写RegisterServices来注册需要注入ioc的类,通过重写Initialize方法在应用启动时执行初始化方法,重写Shutdown方法在应用结束时执行释放资源的方法。

    1. 配置

    您可以使用json或是yml格式对服务进行配置。如下所示,列举了lms服务必要的最少配置。

    rpc:
        host: 0.0.0.0 # 主机地址
        rpcPort: 2201 # rpc通信端口号
        token: ypjdYOzNd4FwENJiEARMLWwK0v7QUHPW # token令牌
    registrycenter:
        connectionStrings: 127.0.0.1:2181 # 服务注册中心地址
        registryCenterType: Zookeeper # 服务注册中心类型
      
    
    1. 完成主机构建后,您可以引用各个微服务模块的应用接口,或是托管服务自身的应用服务。集群内部使用dotntty实现的RPC框架进行通信。

    使用Web主机注册和托管LMS服务

    您可以使用.net的web主机来注册和托管lms服务,通过这种形式构建的服务主机,可以通过引用各个微服务模块的应用接口,通过web主机指定的http端口对外提供访问。web主机可以通过应用接口生成的代理与微服务集群内部各个服务主机进行通信。

    通过web主机注册LMS服务时,一般不需要实现应用接口(即,不需要托管应用服务),只需要引用各个微服务模块的应用接口,通过HTTP端口提供一个与集群外部通信的方式。

    1. 注册LMS服务
        public class Program
        {
            public async static Task Main(string[] args)
            {
                await CreateHostBuilder(args).Build().RunAsync();
            }
    
            public static IHostBuilder CreateHostBuilder(string[] args) =>
                Host.CreateDefaultBuilder(args)
                    .RegisterLmsServices<GatewayModule>()
                    .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });
        }
    
    1. 启动模块
        [DependsOn(typeof(RpcProxyModule),
            typeof(ZookeeperModule),
            typeof(HttpServerModule),
            typeof(DotNettyModule),
            typeof(MessagePackModule)
            )]
        public class GatewayModule : LmsModule
        {
        }
    
    

    与通用主机的指定的启动模块相比,需要额外依赖HttpServerModule模块。

    1. StartUp类

    StartUp类中,您可以通过ConfigureServices配置服务的注入,以及在Configure方法中配置Http请求中间件。例如: 您可以在StartUp类中配置mvc路由、SwaggerAPI稳定等。

    需要注意的是必须在Configure中必须要配置app.ConfigureLmsRequestPipeline(),只有这样Http请求才可以通过lms框架预先设置的中间件。

        public class Startup
        {
            public Startup(IConfiguration configuration)
            {
                Configuration = configuration;
            }
    
            public IConfiguration Configuration { get; }
    
            public void ConfigureServices(IServiceCollection services)
            {
                services.AddControllers();
                services.AddSwaggerGen(c =>
                {
                    c.SwaggerDoc("v1", new OpenApiInfo {Title = "Lms Gateway", Version = "v1"});
                    c.MultipleServiceKey();
                });
            }
    
            public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
            {
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                    app.UseSwagger();
                    app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Lms Gateway Demo v1"));
                }
    
                app.UseHttpsRedirection();
    
                app.UseRouting();
    
                app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
    
                app.ConfigureLmsRequestPipeline();
            }
        }
    

    应用接口与服务条目

    在一个微服务模块中,您可以通过定义应用接口来提供相应的服务条目,应用接口只需要通过ServiceRoute特性进行描述。每个应用接口定义的方法都会生成一个服务条目,应用接口就相当于MVC的Controller,服务条目相当于Action。

    一般的,我们会将应用接口单独定义在一个独立的程序集,应用接口的实现定义在另外一个单独的程序集。应用接口程序集可以被其他微服务模块引用,在其他微服务模块中可以通过引用的应用接口生成代理,通过应用接口代理可以方便与服务提供者进行rpc通信。

        [ServiceRoute]
        public interface ITestAppService
        {
           // 应用接口
           // 每个方法都会生成一个服务条目
            [HttpGet("{name:string}")]
            [Governance(ShuntStrategy = AddressSelectorMode.HashAlgorithm)]
            [GetCachingIntercept("ITestAppService.TestOut", "name:{0}")]
            Task<TestOut> Get([HashKey][CacheKey(0)] string name);
        }
    
    

    更多应用接口的说明和配置请参考

    配置

    Lms支持通过json或是yml格式的对框架进行配置。一般的,您可以通过appsettings.json或是appsettings.yml文件对系统进行配置,并且您可以通过appsettings.{Environment}.yml或是appsettings.{Environment}.json指定在不同的运行环境中加载相应的环境变量。有关详细信息,请参阅在 ASP.NET Core 中使用多个环境

    RPC通信参数配置

    配置项 名称 缺省值 备注
    Host 主机地址 0.0.0.0 缺省配置则自动获取当前服务器的IP为rpc服务IP
    RpcPort Rpc通信端口 2200 指定的rpc通信端口号
    MqttPort mqtt协议通信端口 2300 当前暂未实现mqtt通信协议
    UseLibuv 使用libuv 2300 dotnetty通信是否使用libuv网络库,缺省值为true
    IsSsl 使用Ssl加密 false
    SslCertificateName Ssl证书名称 Ssl证书的相对路径全名称
    SslCertificatePassword Ssl证书密码
    SoBacklog dotnetty SoBacklog 8192 过大或过小会影响性能
    RemoveUnhealthServer 移除不健康服务 true 是否从服务注册中心移除不健康的服务提供者

    服务注册中心配置

    配置项 名称 缺省值 备注
    RegistryCenterType 服务注册中心类型 RegistryCenterType.Zookeepe 当前仅实现了zookeeper作为服务注册中心
    ConnectionTimeout 连接超时 20 单位(秒)
    SessionTimeout session会话超时 30 单位(秒)
    OperatingTimeout 操作超时 60 单位(秒)
    ConnectionStrings 服务注册中心地址 支持多服务注册中心,通一个集群的地址使用逗号(,)分割,多个服务注册中心使用(;)进行分割。例如:zookeeper1:2181,zookeeper1:2182,zookeeper1:2183;zookeeper2:2181,zookeeper2:2182,zookeeper2:2183
    RoutePath 服务条目的路由地址 /services/serviceroutes 当服务启动时会自动注册路由信息到服务注册中心
    MqttPtah Mqtt协议的服务条目的路由地址 /services/serviceroutes 暂未实现
    HealthCheckInterval 暂未实现心跳检查
    服务治理相关配置

    可以通过Governance配置节点统一的rpc通信过程进行配置,但是该配置的可以被服务条目的GovernanceAttribute特性进行改写。

    配置项 名称 缺省值 备注
    ShuntStrategy 负载分流策略 rpc通信过程中的服务路由的地址选择器
    ExecutionTimeout 执行超时时间 -1 单位(ms),0或-1表示不会超时,建议值:1000
    MaxConcurrent 允许的最大并发量 100 超过最大的并发量则会路由到其他的服务提供者实例,如果不存在则会发生熔断保护
    FuseSleepDuration 熔断休眠时间 60 单位(s),熔断期间不会被路由到服务提供者实例
    FuseProtection 是否开启熔断保护 true 服务提供者无法到达时,开启熔断保护则不会立即将该服务提供者的实例标识为不健康,但是在熔断休眠时间内该实例不会被路由
    FuseTimes 熔断几次之后标识服务提供者实例不健康
    FailoverCount 故障转移次数 服务提供者不可达时,允许的重新路由的次数,缺省值为0,则服务提供者实例有几个,则会重试几次

    更对关于服务通信的治理请查看服务治理节点相关文档。

    缓存拦截

    在rpc通信过程中,您可以使用缓存拦截。通过使用缓存拦截,可以大大提升系统的性能。在一个应用接口方法配置了缓存拦截,那么在方法执行前,如果存在缓存,则会从缓存中取出数据。

    您可以在服务条目的方法上通过如下特性对缓存拦截进行配置。

    1. GetCachingInterceptAttribute 优先从缓存中读取缓存数据,如果缓存中不存在,才执行本地或是远程方法。

    2. UpdateCachingInterceptAttribute 执行本地或远程方法并更新缓存数据。

    3. RemoveCachingInterceptAttribute 执行本地或远程方法,并删除相应的缓存数据。

    更对缓存拦截的使用和配置请查看缓存拦截文档

  • 相关阅读:
    为什么全局变量一定要初始化?
    SecureCRT 使用密钥登录 Ubuntu
    ubuntu samba 服务器搭建
    Linux 软硬链接的区别及目录权限对软硬链接的影响
    【转载】解析 java 按值传递还是按引用传递
    (转)如何学好C语言
    (转)五个方法成为更好的程序员
    (转)SQLite数据库的加密
    鸟哥Linux私房菜(基础篇)——第十一章:认识与学习Bash
    鸟哥Linux私房菜(基础篇)——第五章:首次登入与在线求助 man page笔记
  • 原文地址:https://www.cnblogs.com/bea084100123/p/14419712.html
Copyright © 2020-2023  润新知