内容简介:参考文章:https://www.ikende.com/blog/83.html新建项目AyTestClusterAPI代码简化了一下,正常API的服务都部署在多台服务器构建应用集群,一般情况都是通过nginx或其他反向代理服务器接管Client的请求,然后针对负载配置进行转发处理。但接下来需要讲解的是通过开源组件实现无中心化的集群负载调用
参考文章:https://www.ikende.com/blog/83.html
新建项目AyTestClusterAPI
代码简化了一下,正常API的服务都部署在多台服务器构建应用集群,一般情况都是通过nginx或其他反向代理服务器接管Client的请求,然后针对负载配置进行转发处理。但接下来需要讲解的是通过开源组件实现无中心化的集群负载调用
定义接口
引用
using BeetleX.FastHttpApi; using BeetleX.FastHttpApi.Clients; using System; using System.Threading.Tasks;
[JsonFormater] [Controller(BaseUrl = "Home")] public interface IDataService { [Get] Task<DateTime> GetTime(); [Get] Task<string> Hello(string name); [Get] Task<bool> Login(string name, string pwd); //[Get] //Task<List<Employee>> Employees(); //[Get] //Task<Employee> EmployeeGet(int id); //[Post] //Task<int> EmployeeAdd(params Employee[] items); //[Post] //Task<Employee> EmployeeEdit([CQuery]int id, Employee emp); //[Get] //Task<List<EmployeeName>> EmployeesGetName(); //[Get] //Task<List<Customer>> Customers(int count); //[Get] //Task<List<CustomerName>> CustomersGetName(); //[Get] //Task<List<Order>> Orders(int? employeeid, string customerid, int index, int size); }
组件支持Task和非Task返回值的方法定义,由于基础网络访问是基于异步,所以最好还是定义Task返回值的方法。如果定义了非Task返回值访问组件内部会同步等待完成返回,在并发服务下这不利于线程资源的利用。
接口定义好之后,就可以通过接口来调用并把请求调用负载到不同服务器的服务上。这样做首先需要定义一个集群化服务访问对象:
private static HttpClusterApi HttpClusterApi = new HttpClusterApi();
HttpClusterApi对象是线程安全的,所以定义成静态即可;也可以根据服务分类来定义不同的HttpClusterApi(之于内部的工作原理这里就不详细解说了,可以到GitHub上过一步了解)。创建了集群接口对象之后就可以用它来创建接口实例。
private static IDataService DataService;
DataService = HttpClusterApi.Create<IDataService>();
同样接口实例也是线程安的,只需要创建一个即可在不同线程和方法里同时调用。其实这样创建接口后还没能正常使用,因为没有定义相应服务地址,可以通过HttpClusterApi添加不同服务地址:
通过 计算机web节点
HttpClusterApi.AddHost("*", Host25, Host29);
以上是所有请求都负载到Host25和Host29,一般情况都不会直这样定义;的优先级是最低的,只有没有匹配到其他url描述的情况才会匹配
平均负载 是一种最常用的方式,主要是把并发请求平均到不同的服务器上;以下是针对employee相关请求的地址负载到5个服务上.
HttpClusterApi.AddHost("employee.*", Host26, Host27, Host28, Host29, Host30);
看了HttpClusterApi是这个对外真正的机器,然后有点像 消息队列,路由到不同的服务器处理
System.Threading.ThreadPool.QueueUserWorkItem(async (o) => { while (true) { try { await DataService.EmployeeGet(2); } catch (Exception e_) { Console.WriteLine(e_.Message); } } });
权重定义 优先给哪个服务器处理
现实中由于服务器配置不同,服务器运行的服务也有所差异,所以一般情况都不会平均化负载;
这时候权重定义就起到一个非常重要的作用,针对不同地址的服务制定不同的权重值
这样可以让服务资源得到更好地利用!
接下来还是针对以上测试代码,针对不同的服务器设置不同的权重
HttpClusterApi.GetUrlNode("employee.*").Add(new string[] { Host26, Host27, Host28 }).Add(Host29,5).Add(Host30,5);
定义备份节点 权重为0,备份的,没有可以用的,就顶上去,权重高的机器恢复了,又移除了
所谓的备份节点,其实就是不参与负载处理,但所有可用点都故障的情况,备份节点就生效。其实在组件中没有所谓的备份节点,不过可以通过0权重这个值来实现。当存在其他重权的节点可用时,0权重的节点是不会存在于权重表中的,只有当所有节点不可用的情况下,0权重的节点才会移入到权重表;当有效节点恢复后0权重的节点也会被移出权重表。
故障迁移和恢复
组件会自动把存在N次连接错的服务地址在权重表中排除出去,所以当服务不可用的情况会短暂有部分请求会引发访问异常;接下来组件会每隔一段时间去检测有问题的服务地址,直到服务连接可用的情况才会把服务地址重新添加回重权表里接受负载轮循处理。
自定义集群信息源
如果在代码中把负载设置写死了,那到增加节点的时候就非常麻烦需要重新发布程序;组件为了解决这一问题制定了一个接口方便使用者制定自己的集群信息来源配置。通过实现INodeSourceHandler并设置到HttpClusterApi即可以动态更新节点信息便于更改和管理。
以下是针对负载源实现的一个HTTP获取负载源信息实现
public class HTTPRemoteSourceHandler : INodeSourceHandler { private HttpClusterApi mHttpClusterApi = new HttpClusterApi(); private IHttpSourceApi mRemoteSourceApi; public HTTPRemoteSourceHandler(string name, params string[] hosts) { mHttpClusterApi.AddHost("*", hosts); mRemoteSourceApi = mHttpClusterApi.Create<IHttpSourceApi>(); Name = name; } public string Name { get; set; } public int UpdateTime { get; set; } = 5; public Task<ApiClusterInfo> Load() { return mRemoteSourceApi._GetCluster(Name); } }
实现是每5秒钟检则一下信息源,集成到HttpClusterApi如下:
HTTPRemoteSourceHandler remoteSourceHandler = new HTTPRemoteSourceHandler("default", "http://localhost:8080"); HttpClusterApi.NodeSourceHandler = remoteSourceHandler; var result = HttpClusterApi.LoadNodeSource();
设置INodeSourceHandler后组件就会检配置信息,检测错误或版本没有变化的情况就不会更新配置。以下是针对测编写的一个HTTP配置服务:
这个网页我也不知道在哪里。
推荐您阅读更多有关于“FastHttpApi,”的文章
以上所述就是小编给大家介绍的《AY学习基于.NET Core的web api框架-FastHttpApi【6/12】》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。