public static ILoadBalance GetLoadBalance(LoadBalanceType type, IConsumerRegister consumerRegister) { switch (type) { case LoadBalanceType.Random: default: return(new RandomLoadBalance(consumerRegister)); } }
public static string GetSlaveConnectionString(LoadBalanceType type) { if (connectConfig.DBCount == 1) { return(connectConfig.MasterConnectionString); } else { return(""); } }
/* * 子节点调用同节点下其他业务,返回经过负载均衡器选择后的 URL */ private async Task <byte[]> CallService(string clientId, RPCCallServicePayload data) { Client client = await NodeHelper.GetClient(clientId); if (client == null) { return(PacketHandler.MakeRPCResponse(ResponseCodeType.NodeOperationFailed)); } NodeData nodeData = await NodeHelper.GetNodeData(clientId); if (nodeData == null) { return(PacketHandler.MakeRPCResponse(ResponseCodeType.NodeOperationFailed)); } var relatedServices = new List <NodeService>(); foreach (var currentService in nodeData.Services) { if (currentService.Key == data.Key) { relatedServices.Add(currentService); } } var keyContext = LoadBalancer.GetKeyContext(clientId, data.Key); LoadBalanceType loadBalancerType = LoadBalanceType.NoLoadBalance; foreach (var config in client.LoadBalancerConfigurations) { if (config.Key == data.Key) { loadBalancerType = config.Type; break; } } NodeService serviceToUse = LoadBalancer.Lease(loadBalancerType, relatedServices, keyContext, HttpContext.Connection.RemoteIpAddress.GetHashCode(), out var hitSessionContext); if (serviceToUse == null) // 负载均衡器返回无可用业务备选 (业务已过期) { return(PacketHandler.MakeRPCResponse(ResponseCodeType.SvcUnavailable)); } hitSessionContext.IncrementFinishedRequests(); return(PacketHandler.MakeRPCResponse(ResponseCodeType.Ok, serviceToUse.NodeUrl)); }
public async Task <object> ServiceMain([FromBody] ServiceRequest request) { if (!PacketHandler.ValidateServiceRequest(request)) { // Bad Request 不记录日志,以防垃圾信息堆积。 return(PacketHandler.MakeResponse(ResponseCodeType.BadRequest)); } request.Key = (request.Key ?? string.Empty).ToLower(); request.ClientId = request.ClientId.ToLower(); Client client = await NodeHelper.GetClient(request.ClientId); if (client == null) { // clientId 找不到就不记录日志。否则数据库中会充满这些未注册的 clientId 的垃圾数据。 return(PacketHandler.MakeResponse(ResponseCodeType.SvcInvalidClientId)); } Stopwatch requestWatch = null; if (client.LogUserRequest) { // 初始化请求计时器并开始计时处理时间 requestWatch = new Stopwatch(); requestWatch.Start(); } // 获取并处理最终用户的 User-Agent 头部。 string userAgentSingle = string.Empty; if (HttpContext.Request.Headers.TryGetValue("user-agent", out var uaHeaders) && uaHeaders.Count > 0) { // 因为 HTTP 规范允许有多个相同的头,而 UA 正常情况下只发送一个,因此只取一个值 userAgentSingle = uaHeaders.ToArray()[0]; } ServiceLog requestLog = null; if (client.LogUserRequest) { requestLog = new ServiceLog() { RequestBegin = DateTime.Now, Key = request.Key, RemoteIp = HttpContext.Connection.RemoteIpAddress.ToString(), RemotePort = HttpContext.Connection.RemotePort, UA = userAgentSingle, Data = (client.LogUserPayload && request.Data != null) ? request.Data.ToString() : string.Empty, ResponseCode = ResponseCodeType.Ok, }; } NodeData nodeData = await NodeHelper.GetNodeData(request.ClientId); if (nodeData == null) { if (client.LogUserRequest) { LogRequest(requestLog, request.ClientId, ResponseCodeType.SvcNotFound, requestWatch, client.LogRolling); } return(PacketHandler.MakeResponse(ResponseCodeType.SvcNotFound)); } // 找到业务 Key 与其注册的所有 URL 以便负载均衡器选择 var services = new List <NodeService>(); foreach (NodeService svc in nodeData.Services) { if (svc.Key == request.Key && svc.Private == false) { services.Add(svc); } } if (services.Count == 0) // 服务未注册(一个URL都没有注册) { if (client.LogUserRequest) { LogRequest(requestLog, request.ClientId, ResponseCodeType.SvcNotFound, requestWatch, client.LogRolling); } return(PacketHandler.MakeResponse(ResponseCodeType.SvcNotFound)); } var keyContext = LoadBalancer.GetKeyContext(request.ClientId, request.Key); LoadBalanceType loadBalancerType = LoadBalanceType.NoLoadBalance; foreach (var config in client.LoadBalancerConfigurations) { if (config.Key == request.Key) { loadBalancerType = config.Type; break; } } NodeService serviceToUse = LoadBalancer.Lease(loadBalancerType, services, keyContext, HttpContext.Connection.RemoteIpAddress.GetHashCode(), out var hitSessionContext); if (serviceToUse == null) // 负载均衡器返回无可用业务备选 (业务已过期) { if (client.LogUserRequest) { LogRequest(requestLog, request.ClientId, ResponseCodeType.SvcUnavailable, requestWatch, client.LogRolling); } return(PacketHandler.MakeResponse(ResponseCodeType.SvcUnavailable)); } hitSessionContext.IncrementCurrentRequests(); try { var remoteHeaders = new Dictionary <string, string[]>(); foreach (var header in HttpContext.Request.Headers) { remoteHeaders.Add(header.Key.ToLower(), header.Value.ToArray()); } var data = await httpClient.RequestNodeService(new Uri(serviceToUse.NodeUrl), request.Data, client.Timeout, request.ClientId, client.ClientSecret, HttpContext.Connection.RemoteIpAddress.ToString(), HttpContext.Connection.RemotePort, remoteHeaders); if (data == null) { if (client.LogUserRequest) { LogRequest(requestLog, request.ClientId, ResponseCodeType.NodeResponseError, requestWatch, client.LogRolling); } hitSessionContext.IncrementFailedRequests(); return(PacketHandler.MakeResponse(ResponseCodeType.NodeResponseError)); } if (client.LogUserRequest) { LogRequest(requestLog, request.ClientId, ResponseCodeType.Ok, requestWatch, client.LogRolling); } return(PacketHandler.MakeResponse(ResponseCodeType.Ok, data)); } catch (TaskCanceledException) { hitSessionContext.IncrementFailedRequests(); if (client.LogUserRequest) { LogRequest(requestLog, request.ClientId, ResponseCodeType.NodeResponseTimedout, requestWatch, client.LogRolling); } return(PacketHandler.MakeResponse(ResponseCodeType.NodeResponseTimedout)); } catch { hitSessionContext.IncrementFailedRequests(); if (client.LogUserRequest) { LogRequest(requestLog, request.ClientId, ResponseCodeType.NodeNetworkException, requestWatch, client.LogRolling); } return(PacketHandler.MakeResponse(ResponseCodeType.NodeNetworkException)); } finally { hitSessionContext.DecrementCurrentRequests(); hitSessionContext.IncrementFinishedRequests(); } }
public IPEndPoint GetServieByLoadBalane(List <FlowControlEndPoint> lbEndPoints, IPEndPoint clientIp, LoadBalanceType type = LoadBalanceType.IPHash, ServiceConfigureInfo configure = null) { var result = default(FlowControlEndPoint); if (lbEndPoints != null && lbEndPoints.Any()) { //若没有客户端IP则默认调用随机 if (clientIp == null && type == LoadBalanceType.IPHash) { type = LoadBalanceType.Random; } switch (type) { //随机 case LoadBalanceType.Random: result = lbEndPoints.OrderBy(x => Guid.NewGuid()).FirstOrDefault(); break; //轮询 case LoadBalanceType.Polling: result = TargetIp == null?lbEndPoints.FirstOrDefault() : lbEndPoints.Any(x => x.HashSort > TargetIpSortInex) ? lbEndPoints.First(x => x.HashSort > TargetIpSortInex) : lbEndPoints.First(); TargetIp = result.GetEndPoint(); TargetIpSortInex = result.HashSort; break; //IP哈希 case LoadBalanceType.IPHash: result = lbEndPoints[Math.Abs(clientIp.GetHashCode()) % lbEndPoints.Count]; break; //最小连接 case LoadBalanceType.MinConnections: result = lbEndPoints.OrderBy(x => x.ConnectCount).FirstOrDefault(); break; } } if (configure != null) { configure.ChangeConnectCount(result.GetEndPoint(), true); } return(result.GetEndPoint()); }
public IPEndPoint GetServieByLoadBalane(List <IPEndPoint> lbEndPoints, IPEndPoint clientIp, LoadBalanceType type = LoadBalanceType.IPHash) { return(GetServieByLoadBalane(lbEndPoints.GetFlowControlEndPoints(), clientIp, type)); }