您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
本篇文章给大家分享的是有关使用.net core怎么实现微服务,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。
远程服务客户端代理
public class RemoteServiceProxy : IApiService
{
public string Address { get; set; } //服务地址private ApiActionResult PostHttpRequest(string interfaceId, string methodId, params object[] p)
{
ApiActionResult apiRetult = null;
using (var httpClient = new HttpClient())
{
var param = new ArrayList(); //包装参数
foreach (var t in p)
{
if (t == null)
{
param.Add(null);
}
else
{
var ns = t.GetType().Namespace;
param.Add(ns != null && ns.Equals("System") ? t : JsonConvert.SerializeObject(t));
}
}
var postContentStr = JsonConvert.SerializeObject(param);
HttpContent httpContent = new StringContent(postContentStr);
if (CurrentUserId != Guid.Empty)
{
httpContent.Headers.Add("UserId", CurrentUserId.ToString());
}
httpContent.Headers.Add("EnterpriseId", EnterpriseId.ToString());
httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var url = Address.TrimEnd('/') + $"/{interfaceId}/{methodId}";
AppRuntimes.Instance.Loger.Debug($"httpRequest:{url},data:{postContentStr}");
var response = httpClient.PostAsync(url, httpContent).Result; //提交请求
if (!response.IsSuccessStatusCode)
{
AppRuntimes.Instance.Loger.Error($"httpRequest error:{url},statuscode:{response.StatusCode}");
throw new ICVIPException("网络异常或服务响应失败");
}
var responseStr = response.Content.ReadAsStringAsync().Result;
AppRuntimes.Instance.Loger.Debug($"httpRequest response:{responseStr}");
apiRetult = JsonConvert.DeserializeObject<ApiActionResult>(responseStr);
}
if (!apiRetult.IsSuccess)
{
throw new BusinessException(apiRetult.Message ?? "服务请求失败");
}
return apiRetult;
}
//有返回值的方法代理
public T Invoke<T>(string interfaceId, string methodId, params object[] param)
{
T rs = default(T);
var apiRetult = PostHttpRequest(interfaceId, methodId, param);
try
{
if (typeof(T).Namespace == "System")
{
rs = (T)TypeConvertUtil.BasicTypeConvert(typeof(T), apiRetult.Data);
}
else
{
rs = JsonConvert.DeserializeObject<T>(Convert.ToString(apiRetult.Data));
}
}
catch (Exception ex)
{
AppRuntimes.Instance.Loger.Error("数据转化失败", ex);
throw;
}
return rs;
}
//没有返回值的代理
public void InvokeWithoutReturn(string interfaceId, string methodId, params object[] param)
{
PostHttpRequest(interfaceId, methodId, param);
}
}远程服务端http接入段统一入口
[Route("api/svc/{interfaceId}/{methodId}"), Produces("application/json")]
public async Task<ApiActionResult> Process(string interfaceId, string methodId)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
ApiActionResult result = null;
string reqParam = string.Empty;
try
{
using (var reader = new StreamReader(Request.Body, Encoding.UTF8))
{
reqParam = await reader.ReadToEndAsync();
}
AppRuntimes.Instance.Loger.Debug($"recive client request:api/svc/{interfaceId}/{methodId},data:{reqParam}");
ArrayList param = null;
if (!string.IsNullOrWhiteSpace(reqParam))
{
//解析参数
param = JsonConvert.DeserializeObject<ArrayList>(reqParam);
}
//转交本地服务处理中心处理
var data = LocalServiceExector.Exec(interfaceId, methodId, param);
result = ApiActionResult.Success(data);
}
catch BusinessException ex) //业务异常
{
result = ApiActionResult.Error(ex.Message);
}
catch (Exception ex)
{
//业务异常
if (ex.InnerException is BusinessException)
{
result = ApiActionResult.Error(ex.InnerException.Message);
}
else
{
AppRuntimes.Instance.Loger.Error($"调用服务发生异常{interfaceId}-{methodId},data:{reqParam}", ex);
result = ApiActionResult.Fail("服务发生异常");
}
}
finally
{
stopwatch.Stop();
AppRuntimes.Instance.Loger.Debug($"process client request end:api/svc/{interfaceId}/{methodId},耗时[ {stopwatch.ElapsedMilliseconds} ]毫秒");
}
//result.Message = AppRuntimes.Instance.GetCfgVal("ServerName") + " " + result.Message;
result.Message = result.Message;
return result;
}本地服务中心通过接口名和方法名,找出具体的实现类的方法,并使用传递的参数执行,ps:因为涉及到反射获取具体的方法,暂不支持相同参数个数的方法重载.仅支持不同参数个数的方法重载.
public static object Exec(string interfaceId, string methodId, ArrayList param)
{
var svcMethodInfo = GetInstanceAndMethod(interfaceId, methodId, param.Count);
var currentMethodParameters = new ArrayList();
for (var i = 0; i < svcMethodInfo.Paramters.Length; i++)
{
var tempParamter = svcMethodInfo.Paramters[i];
if (param[i] == null)
{
currentMethodParameters.Add(null);
}
else
{
if (!tempParamter.ParameterType.Namespace.Equals("System") || tempParamter.ParameterType.Name == "Byte[]")
{
currentMethodParameters.Add(JsonConvert.DeserializeObject(Convert.ToString(param[i]), tempParamter.ParameterType)
}
else
{
currentMethodParameters.Add(TypeConvertUtil.BasicTypeConvert(tempParamter.ParameterType, param[i]));
}
}
}
return svcMethodInfo.Invoke(currentMethodParameters.ToArray());
}
private static InstanceMethodInfo GetInstanceAndMethod(string interfaceId, string methodId, int paramCount)
{
var methodKey = $"{interfaceId}_{methodId}_{paramCount}";
if (methodCache.ContainsKey(methodKey))
{
return methodCache[methodKey];
}
InstanceMethodInfo temp = null;
var svcType = ServiceFactory.GetSvcType(interfaceId, true);
if (svcType == null)
{
throw new ICVIPException($"找不到API接口的服务实现:{interfaceId}");
}
var methods = svcType.GetMethods().Where(t => t.Name == methodId).ToList();
if (methods.IsNullEmpty())
{
throw new BusinessException($"在API接口[{interfaceId}]的服务实现中[{svcType.FullName}]找不到指定的方法:{methodId}");
}
var method = methods.FirstOrDefault(t => t.GetParameters().Length == paramCount);
if (method == null)
{
throw new ICVIPException($"在API接口中[{interfaceId}]的服务实现[{svcType.FullName}]中,方法[{methodId}]参数个数不匹配");
}
var paramtersTypes = method.GetParameters();
object instance = null;
try
{
instance = Activator.CreateInstance(svcType);
}
catch (Exception ex)
{
throw new BusinessException($"在实例化服务[{svcType}]发生异常,请确认其是否包含一个无参的构造函数", ex);
}
temp = new InstanceMethodInfo()
{
Instance = instance,
InstanceType = svcType,
Key = methodKey,
Method = method,
Paramters = paramtersTypes
};
if (!methodCache.ContainsKey(methodKey))
{
lock (_syncAddMethodCacheLocker)
{
if (!methodCache.ContainsKey(methodKey))
{
methodCache.Add(methodKey, temp);
}
}
}
return temp;服务配置,指示具体的服务的远程地址,当未配置的服务默认为本地服务.
[
{
"ServiceId": "XZL.Api.IOrderService",
"Address": "http://localhost:8801/api/svc"
},
{
"ServiceId": "XZL.Api.IUserService",
"Address": "http://localhost:8802/api/svc"
}
]AppRuntime.Instance.GetService<TService>()的实现.
private static List<(string typeName, Type svcType)> svcTypeDic;
private static ConcurrentDictionary<string, Object> svcInstance = new ConcurrentDictionary<string, object>();
public static TService GetService<TService>()
{
var serviceId = typeof(TService).FullName;
//读取服务配置
var serviceInfo = ServiceConfonfig.Instance.GetServiceInfo(serviceId);
if (serviceInfo == null)
{
return (TService)Activator.CreateInstance(GetSvcType(serviceId));
}
else
{
var rs = GetService<TService>(serviceId + (serviceInfo.IsRemote ? "|Remote" : ""), serviceInfo.IsSingle);
if (rs != null && rs is RemoteServiceProxy)
{
var temp = rs as RemoteServiceProxy;
temp.Address = serviceInfo.Address; //指定服务地址
}
return rs;
}
}
public static TService GetService<TService>(string interfaceId, bool isSingle)
{
//服务非单例模式
if (!isSingle)
{
return (TService)Activator.CreateInstance(GetSvcType(interfaceId));
}
object obj = null;
if (svcInstance.TryGetValue(interfaceId, out obj) && obj != null)
{
return (TService)obj;
}
var svcType = GetSvcType(interfaceId);
if (svcType == null)
{
throw new ICVIPException($"系统中未找到[{interfaceId}]的代理类");
}
obj = Activator.CreateInstance(svcType);
svcInstance.TryAdd(interfaceId, obj);
return (TService)obj;
}
//获取服务的实现类
public static Type GetSvcType(string interfaceId, bool? isLocal = null)
{
if (!_loaded)
{
LoadServiceType();
}
Type rs = null;
var tempKey = interfaceId;
var temp = svcTypeDic.Where(x => x.typeName == tempKey).ToList();
if (temp == null || temp.Count == 0)
{
return rs;
}
if (isLocal.HasValue)
{
if (isLocal.Value)
{
rs = temp.FirstOrDefault(t => !typeof(RemoteServiceProxy).IsAssignableFrom(t.svcType)).svcType;
}
else
{
rs = temp.FirstOrDefault(t => typeof(RemoteServiceProxy).IsAssignableFrom(t.svcType)).svcType;
}
}
else
{
rs = temp[0].svcType;
}
return rs;
}为了性能影响,我们在程序启动的时候可以将当前所有的ApiService类型缓存.
public static void LoadServiceType()
{
if (_loaded)
{
return;
}
lock (_sync)
{
if (_loaded)
{
return;
}
try
{
svcTypeDic = new List<(string typeName, Type svcType)>();
var path = AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory;
var dir = new DirectoryInfo(path);
var files = dir.GetFiles("XZL*.dll");
foreach (var file in files)
{
var types = LoadAssemblyFromFile(file);
svcTypeDic.AddRange(types);
}
_loaded = true;
}
catch
{
_loaded = false;
}
}
}
//加载指定文件中的ApiService实现
private static List<(string typeName, Type svcType)> LoadAssemblyFromFile(FileInfo file)
{
var lst = new List<(string typeName, Type svcType)>();
if (file.Extension != ".dll" && file.Extension != ".exe")
{
return lst;
}
try
{
var types = Assembly.Load(file.Name.Substring(0, file.Name.Length - 4))
.GetTypes()
.Where(c => c.IsClass && !c.IsAbstract && c.IsPublic);
foreach (Type type in types)
{
//客户端代理基类
if (type == typeof(RemoteServiceProxy))
{
continue;
}
if (!typeof(IApiService).IsAssignableFrom(type))
{
continue;
}
//绑定现类
lst.Add((type.FullName, type));
foreach (var interfaceType in type.GetInterfaces())
{
if (!typeof(IApiService).IsAssignableFrom(interfaceType))
{
continue;
}
//绑定接口与实际实现类
lst.Add((interfaceType.FullName, type));
}
}
}
catch
{
}
return lst;
}具体api远程服务代理示例
public class UserServiceProxy : RemoteServiceProxy, IUserService
{
private string serviceId = typeof(IUserService).FullName;
public void IncreaseScore(int userId,int score)
{
return InvokeWithoutReturn(serviceId, nameof(IncreaseScore), userId,score);
}
public UserInfo GetUserById(int userId)
{
return Invoke<UserInfo >(serviceId, nameof(GetUserById), userId);
}
}以上就是使用.net core怎么实现微服务,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注亿速云行业资讯频道。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。