接口压力测试的问题续到这里也该解决了,问题已经定位,下面就是实施了。
在应用启动时注册HttpApi接口,使用时自动解析。
项目引用了类库WebApiClient,这里继续使用。WebApiClient是开源的第三方类库,对HttpClient进行了封装,性能接近原生的HttpClient。
在启动类Startup中引入WebApiClient,并进行配置。
services.AddHttpApi<RunGo.OAuth2._0_Base.IRealize>(); services.ConfigureHttpApi<RunGo.OAuth2._0_Base.IRealize>(option => { option.HttpHost = new System.Uri(_Configuration["Sign:AdminHost"]); //option.JsonSerializeOptions.Converters.Add(new IsoDateTimeConverter("yyyy-MM-dd HH:mm:ss")); });IRealize是定义HttpApi接口的接口类。
public interface IRealize:IDisposable, IHttpApi { #region 管理中心提供的接口 /// <summary> /// 发送短信 /// </summary> /// <returns></returns> [HttpPost("/api/services/Admin/OAuth2/SetMessage")] Task<string> SetMessage([JsonContent] SetMessageInput input); /// <summary> /// 忘记密码 /// </summary> /// <returns></returns> [HttpPost("/api/services/Admin/OAuth2/ForgotPassword")] Task<string> ForgotPassword([JsonContent] ForgotPasswordInput input); /// <summary> /// 注册 /// </summary> /// <returns></returns> [HttpPost("/api/services/Admin/OAuth2/OAuthResign")] Task<string> OAuthResign([JsonContent] OAuthResignInput input); /// <summary> /// 登录step1 /// </summary> /// <returns></returns> [HttpPost("/api/services/Admin/OAuth2/OAuthLoginIn")] Task<string> GetOAuthOfAdmin([JsonContent] GetOAuthOfAdminInput input); /// <summary> /// 登录step2 /// </summary> /// <returns></returns> [HttpPost("/api/services/Admin/OAuth2/Get_UserInfo")] Task<string> GetOAuthForUserInfo([JsonContent] GetOAuthForUserInfoInput input); /// <summary> /// 获取用户信息 /// </summary> /// <returns></returns> [HttpPost("/api/services/Admin/OAuth2/Get_UserInfoByToken")] Task<string> PostUserInfoByToken([JsonContent] PostUserInfoByTokenInput input); /// <summary> /// 应答登录 /// </summary> /// <returns></returns> [HttpPost("/api/services/Admin/OAuth2/AnswerLoginRequest")] Task<string> AnswerLoginRequest([JsonContent] AnswerLoginRequestInput input); /// <summary> /// 退出登陆 /// </summary> /// <returns></returns> [HttpPost("/api/services/Admin/OAuth2/LoginOut")] Task<string> LoginOut([JsonContent] LoginOutInput input); /// <summary> /// 校验token /// </summary> /// <returns></returns> [HttpPost("/api/services/Admin/OAuth2/CheckToken")] Task<CheckResultDto> CheckToken([JsonContent] CheckTokenInput input); #endregion }在需要使用的地方通过构造函数实现依赖注入。同时注入配置管理器IConfiiguration和部分局部变量,用于获取配置信息。
在使用时直接调用,剩下的交给依赖注入框架。
/// <summary> /// 登录接口 /// </summary> /// <returns></returns> [Route("api/services/app/Login_OAuth/Login")] [HttpPost] [HttpOptions] [DontWrapResult] public virtual Task<dynamic> Login(LoginDto loginDto) { //return realize.GetOAuthOfAdmin(new RunGo.OAuth2._0_Base.GetOAuthOfAdminDto() //{ // userName = loginDto.userName, // passWord = loginDto.passWord, // response_type = "code", // state = loginDto.state, // source = loginDto.source, //}); var info = $"网关独立请求测试"; GetOAuthOfAdminInput inputDto = new GetOAuthOfAdminInput() { userName=loginDto.userName, passWord=loginDto.passWord, response_type="code", client_id=clientId, client_secret= clientSecret, tenantId=tenantId, redirect_uri=redirectUri, state=loginDto.state, source=loginDto.source }; string resultJson = _realize.GetOAuthOfAdmin(inputDto).Result; info = new { result = resultJson }.ToJson(); return Task.FromResult<dynamic>(info); }
改造完成,启动,测试。
并发100,总时长1s,平均249ms;并发500,总时长4s,平均3000ms;并发1000,总时长16s,平均10200ms;并发1500,总时长45s,平均12000ms;并发1500以上有概率报错。总体上已经满足要求了。
至此压力测试问题解决。
----------------------------------------------------------------------------------------------------------------------------
推荐GitHub上的Dotnet Core开源项目集合,汇集了很多优秀的开源项目,由国内多名技术专家维护。日常用到的就有上面提到的Http请求类库WebApiClient、支持国产数据库的ORM框架FreeSql、适合DTO模式导入导出Excel的Magicodes.IE、分布式数据同步组件CAP等。