You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@shenyu.apache.org by "邪龙(dragon-zhang)" <19...@qq.com.INVALID> on 2022/04/25 04:38:51 UTC

回复: some bugfix and refactor for shenyu

Hi, xiaoyu, thanks for response. Under my local stress test, `HttpClient` can reach about 2500 QPS without thread pool configuration:
```java
&nbsp; &nbsp; @Bean
&nbsp; &nbsp; public HttpClient httpClient(final HttpClientProperties properties) {
&nbsp; &nbsp; &nbsp; &nbsp; HttpClientProperties.Pool pool = properties.getPool();
&nbsp; &nbsp; &nbsp; &nbsp; ConnectionProvider connectionProvider = buildConnectionProvider(pool);
&nbsp; &nbsp; &nbsp; &nbsp; HttpClient httpClient = HttpClient.create(connectionProvider)
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .tcpConfiguration(tcpClient -&gt; {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (Objects.nonNull(properties.getConnectTimeout())) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tcpClient = tcpClient.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, properties.getConnectTimeout());
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; HttpClientProperties.Proxy proxy = properties.getProxy();
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (StringUtils.isNotEmpty(proxy.getHost())) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tcpClient = setTcpClientProxy(tcpClient, proxy);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tcpClient = tcpClient.doOnConnected(connection -&gt; {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; connection.addHandlerLast(new IdleStateHandler(properties.getReaderIdleTime(), properties.getWriterIdleTime(), properties.getAllIdleTime(), TimeUnit.MILLISECONDS));
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; connection.addHandlerLast(new WriteTimeoutHandler(properties.getWriteTimeout(), TimeUnit.MILLISECONDS));
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; connection.addHandlerLast(new ReadTimeoutHandler(properties.getReadTimeout(), TimeUnit.MILLISECONDS));
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; });
//here not config
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return tcpClient;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; });
&nbsp; &nbsp; &nbsp; &nbsp; HttpClientProperties.Ssl ssl = properties.getSsl();
&nbsp; &nbsp; &nbsp; &nbsp; if (StringUtils.isNotEmpty(ssl.getKeyStorePath())
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; || ArrayUtils.isNotEmpty(ssl.getTrustedX509CertificatesForTrustManager())
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; || ssl.isUseInsecureTrustManager()) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; httpClient = httpClient.secure(sslContextSpec -&gt; setSsl(sslContextSpec, ssl));
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; if (properties.isWiretap()) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; httpClient = httpClient.wiretap(true);
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; return httpClient.keepAlive(properties.isKeepAlive());
&nbsp; &nbsp; }

```
And about 2600 QPS after configuration:
```java
&nbsp; &nbsp; @Bean
&nbsp; &nbsp; public HttpClient httpClient(final HttpClientProperties properties,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;final ObjectProvider<LoopResources&gt; provider) {
&nbsp; &nbsp; &nbsp; &nbsp; HttpClientProperties.Pool pool = properties.getPool();
&nbsp; &nbsp; &nbsp; &nbsp; ConnectionProvider connectionProvider = buildConnectionProvider(pool);
&nbsp; &nbsp; &nbsp; &nbsp; HttpClient httpClient = HttpClient.create(connectionProvider)
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .tcpConfiguration(tcpClient -&gt; {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (Objects.nonNull(properties.getConnectTimeout())) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tcpClient = tcpClient.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, properties.getConnectTimeout());
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; HttpClientProperties.Proxy proxy = properties.getProxy();
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (StringUtils.isNotEmpty(proxy.getHost())) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tcpClient = setTcpClientProxy(tcpClient, proxy);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tcpClient = tcpClient.doOnConnected(connection -&gt; {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; connection.addHandlerLast(new IdleStateHandler(properties.getReaderIdleTime(), properties.getWriterIdleTime(), properties.getAllIdleTime(), TimeUnit.MILLISECONDS));
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; connection.addHandlerLast(new WriteTimeoutHandler(properties.getWriteTimeout(), TimeUnit.MILLISECONDS));
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; connection.addHandlerLast(new ReadTimeoutHandler(properties.getReadTimeout(), TimeUnit.MILLISECONDS));
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; });
//add the config here
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; final LoopResources loopResources = provider.getIfAvailable();
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (Objects.nonNull(loopResources)) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tcpClient = tcpClient.runOn(loopResources);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return tcpClient;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; });
&nbsp; &nbsp; &nbsp; &nbsp; HttpClientProperties.Ssl ssl = properties.getSsl();
&nbsp; &nbsp; &nbsp; &nbsp; if (StringUtils.isNotEmpty(ssl.getKeyStorePath())
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; || ArrayUtils.isNotEmpty(ssl.getTrustedX509CertificatesForTrustManager())
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; || ssl.isUseInsecureTrustManager()) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; httpClient = httpClient.secure(sslContextSpec -&gt; setSsl(sslContextSpec, ssl));
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; if (properties.isWiretap()) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; httpClient = httpClient.wiretap(true);
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; return httpClient.keepAlive(properties.isKeepAlive());
&nbsp; &nbsp; }

```


------------------&nbsp;原始邮件&nbsp;------------------
发件人:                                                                                                                        "dev"                                                                                    <xiaoyu@apache.org&gt;;
发送时间:&nbsp;2022年4月25日(星期一) 上午10:36
收件人:&nbsp;"dev"<dev@shenyu.apache.org&gt;;

主题:&nbsp;Re: some bugfix and refactor for shenyu



Hi

Looks good for me,

BTW,TcpClient#runOn` have better performance?

邪龙(dragon-zhang) <1936978077@qq.com.invalid&gt; 于2022年4月24日周日 21:32写道:
&gt;
&gt; Dear community:
&gt;
&gt; PR[1] use `TcpClient#runOn` and configure `DefaultLoopResources`&amp;nbsp;as a singleton bean, and finally fixes ISSUE[2] correctly. I'm sorry for the previous wrong submission;
&gt;
&gt;
&gt; PR[3] refactor part of the logic of `ShenyuThreadPoolExecutor` to make it more extensible, and fixed a previous bug(see `workQueue.setExecutor(this);` line in `ShenyuThreadPoolExecutor`);
&gt;
&gt;
&gt; Now `MemoryLimitCalculator#maxAvailable` will call JNI every time to get the latest JVM memory information, PR [4] adjusts it to get it every 50ms;
&gt;
&gt;
&gt; If you are free, please see the PR[1], PR[3], PR[4] and help these PRs to be better.
&gt;
&gt; Looking forward to your reply.
&gt;
&gt; [1]&amp;nbsp;https://github.com/apache/incubator-shenyu/pull/3314
&gt; [2]&amp;nbsp;https://github.com/apache/incubator-shenyu/issues/3063
&gt; [3]&amp;nbsp;https://github.com/apache/incubator-shenyu/pull/3315
&gt; [4]&amp;nbsp;https://github.com/apache/incubator-shenyu/pull/3316