接口压力测试的问题续到这里也该解决了,问题已经定位,下面就是实施了。
在应用启动时注册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等。