Dapr .NetCore 并发限流 电脑版发表于:2021/12/26 17:12 ![](https://img.tnblog.net/arcimg/hb/896fd38e95b346f9a0d98c54b135bb94.jpg) >#Dapr .NetCore 并发限流 [TOC] 限流控制 ------------ tn2>使用限制dapr中间件来限制每秒请求数(当dapr请求dapr的时候我们进行限流),大致如下图所示: ![](https://img.tnblog.net/arcimg/hb/9a670e6db57e477fb0a2d22414181e0e.png) >###创建限流组件 tn2>在`~/.dapr/components/`下创建限流中间件,文件名为`bf.yaml` ```yaml apiVersion: dapr.io/v1alpha1 kind: Component metadata: name: ratelimit spec: type: middleware.http.ratelimit version: v1 metadata: - name: maxRequestsPerSecond value: 1 ``` tn2>将`maxRequestsPerSecond`设置为1,表示同一时间内最多允许一个请求处理 >### 添加相关dapr配置 tn2>在`~/.dapr/config.yaml`进行添加中间件配置 ```yaml apiVersion: dapr.io/v1alpha1 kind: Configuration metadata: name: daprConfig spec: tracing: samplingRate: "1" zipkin: endpointAddress: http://localhost:9411/api/v2/spans httpPipeline: handlers: - name: ratelimit type: middleware.http.ratelimit ``` tn>注意我这里修改在之后运行的项目将全部都受到影响,建议自行定义一个config yaml并在运行时单独运用。 >### 客户端代码定义 tn2>对myserver appid进行请求`/Request/v3`方法。 ```csharp [HttpGet("sendv3")] public async Task<string> Sendv3() { _logger.LogInformation($"进来了"); var idnumber = new Random().Next(0,99); var mydata = new MyClass(idnumber,$"MyClass{idnumber}"); var client = DaprClient.CreateInvokeHttpClient(appId: "myserver"); // http的方式 var response = await client.PostAsJsonAsync("/Request/v3", mydata); if (response.IsSuccessStatusCode) { var newdata = await response.Content.ReadFromJsonAsync<MyClass>(); _logger.LogInformation($"得到服务器端处理的新数据:{newdata.Id} {newdata.Name}"); return JsonConvert.SerializeObject(newdata); }else{ return "bad"; } } public class MyClass { public MyClass(){} public MyClass(int id,string name) { Id = id; Name = name; } public int Id { get; set; } public string Name { get; set; } } ``` >### 服务器端定义 tn2>我们让其等待三秒 ```csharp [HttpPost("v3")] public MyClass Getv3(MyClass myClass) { Thread.Sleep(3000); _logger.LogInformation($"{DateTime.Now} {myClass.Id} {myClass.Name} finish!"); myClass.Name = myClass.Name + " ---- Finish"; return myClass; } ``` >### 运行测试 ```bash dapr run --app-id myserver --app-port 5002 --dapr-http-port 3501 -- dotnet InvokeMethodServer.dll --urls="http://*:5002" dapr run --app-id dotnetapp --app-port 5001 --dapr-http-port 3500 -- dotnet InvokeMethod.dll --urls="http://*:5001" ``` tn2>我们通过Jmeter进行10个并发请求进行测试 ![](https://img.tnblog.net/arcimg/hb/a20b7e6214554a8cb881469182876b4f.png) ![](https://img.tnblog.net/arcimg/hb/7bdc5c2b338b4f069683e43e545b1e19.png) ![](https://img.tnblog.net/arcimg/hb/dfd169a26680431b943f472bf574260a.png) ![](https://img.tnblog.net/arcimg/hb/02df21b2f9c2403481ce85ecbd691427.png) tn2>我们并发请求了10个但是只处理了一个,其他的都失败了。并且吞吐量控制在了`3.1/sec`。 tn>可能会有一些同志感到又些疑惑,既然是全局限流,为啥子客户端不受影响。因为我们请求的客户端方法不是通过dapr的中间件去请求的,所以自然也不会受影响。 (接下来dapr还提供一种并发控制) 并发控制 ------------ tn2>dapr另一种控制是:dapr边车访问应用时进行限制。参考下图所示 ![](https://img.tnblog.net/arcimg/hb/a5bc0714c6b04185911ec0aa0ad994ca.png) tn2>我们先去掉中间件处理。然后运行服务器端时添加上` app-max-concurrency`参数,用于设置最大并发处理的数量。 ```bash dapr run --app-max-concurrency 1 --app-id myserver --app-port 5002 --dapr-http-port 3501 -- dotnet InvokeMethodServer.dll --urls="http://*:5002" ``` tn2>在k8s中可以这样添加上这个字段 ```bash dapr.io/app-max-concurrency: "1" ``` tn>自行尝试吧