查看原文
其他

.NET Core下去中心化访问HTTP服务集群

DotNet 2019-08-03

(给DotNet加星标,提升.Net技能


转自:smark

cnblogs.com/smark/p/10114989.html


一般应用服务都会部署到多台服务器之上


1、可以通过硬件得到更多的并发处理能力;


2、可以避免单点太故障的出现,从而确保服务7X24有效运作。



public class HomeController : Controller
{
   [HttpPost]
   public int EmployeeAdd([FromBody]List<Employee> items)
   
{
       return items == null ? 0 : items.Count;
   }
   [HttpPost]
   public Employee EmployeeEdit(int id, [FromBody]Employee emp)
   
{
       Employee record = DataHelper.Employees.Find(e => e.EmployeeID == id);
       if (record != null)
       {
           record.City = emp.City;
           record.Address = emp.Address;
           record.Title = emp.Title;
           record.HomePhone = emp.HomePhone;
           return record;
       }
       return null;
   }

   public object EmployeesGetName()
   
{
       return from e in DataHelper.Employees select new { ID = e.EmployeeID, Name = e.FirstName + " " + e.LastName };
   }

   public object Customers(int count)
   
{
       List<Customer> result = new List<Customer>();
       if (count > DataHelper.Customers.Count)
           count = DataHelper.Customers.Count;
       for (int i = 0; i < count; i++)
       {
           result.Add(DataHelper.Customers[i]);
       }
       return result;
   }

   public object CustomersGetName()
   
{
       return from c in DataHelper.Customers select new { ID = c.CustomerID, Name = c.CompanyName };
   }
}




定义访问接口


组件支持通过接口的方式来描述HTTP接口服务,接口的访问方式对使用和维护都具有着极大的便利性,以下是针对以上服务描述的接口


[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);
}



private static HttpClusterApi HttpClusterApi = new HttpClusterApi();


HttpClusterApi对象是线程安全的,所以定义成静态即可;也可以根据服务分类来定义不同的HttpClusterApi(之于内部的工作原理这里就不详细解说了,可以到GitHub上过一步了解)。创建了集群接口对象之后就可以用它来创建接口实例。


private static IDataService DataService;
DataService = HttpClusterApi.Create<IDataService>();


同样接口实例也是线程安的,只需要创建一个即可在不同线程和方法里同时调用。其实这样创建接口后还没能正常使用,因为没有定义相应服务地址,可以通过HttpClusterApi添加不同服务地址:


HttpClusterApi.AddHost("*", Host25, Host29);


以上是所有请求都负载到Host25和Host29,一般情况都不会直这样定义;*的优先级是最低的,只有没有匹配到其他url描述的情况才会匹配*


平均负载


平均负载是一种最常用的方式,主要是把并发请求平均到不同的服务器上;以下是针对employee相关请求的地址负载到5个服务上.


HttpClusterApi.AddHost("employee.*", Host26, Host27, Host28, Host29, Host30);


接下简单地测试一下


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);


以上代码分别把Host29和Host30的权重设置为5其他均为10.





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 = await HttpClusterApi.LoadNodeSource();


设置INodeSourceHandler后组件就会检配置信息,检测错误或版本没有变化的情况就不会更新配置。以下是针对测编写的一个HTTP配置服务:



详细的代码可以访问 https://github.com/IKende/FastHttpApi


推荐阅读

(点击标题可跳转阅读)

.NET Core 中实现AOP编程

ASP.NET Core 被低估的过滤器

Visual Studio Code 1.30 发布


看完本文有收获?请转发分享给更多人

关注「DotNet」加星标,提升.Net技能 

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存