1、使用reactor-netty提供的server和client,同时存在
直接来到DefaultLoopResources.java中,可以看到两个方法
@Override
public EventLoopGroup onClient(boolean useNative) {
if (useNative && LoopResources.hasNativeSupport()) {
return cacheNativeClientLoops();
}
return cacheNioClientLoops();
}
@Override
public EventLoopGroup onServer(boolean useNative) {
if (useNative && LoopResources.hasNativeSupport()) {
return cacheNativeServerLoops();
}
return cacheNioServerLoops();
}
然后进入cacheNativeClientLoops()中
EventLoopGroup cacheNativeClientLoops() {
EventLoopGroup eventLoopGroup = cacheNativeClientLoops.get();
if (null == eventLoopGroup) {
EventLoopGroup newEventLoopGroup = LoopResources.colocate(cacheNativeServerLoops());
if (!cacheNativeClientLoops.compareAndSet(null, newEventLoopGroup)) {
// Do not shutdown newEventLoopGroup as this will shutdown the server loops
}
eventLoopGroup = cacheNativeClientLoops();
}
return eventLoopGroup;
}
可以看到调了cacheNativeServerLoops()方法,实现了与server共用EventLoopGroup.
那么在编程中, 如何指定EventLoopGroup线程数呢?那么请转到reactor.netty.resources.LoopResources中
int DEFAULT_IO_WORKER_COUNT = Integer.parseInt(System.getProperty(
ReactorNetty.IO_WORKER_COUNT,
"" + Math.max(Runtime.getRuntime().availableProcessors(), 4)));
其中ReactorNetty.IO_WORKER_COUNT值为"reactor.netty.ioWorkerCount", 那可以简单通过设置这个值来实现:
System.setProperty("reactor.netty.ioWorkerCount", "2");
或者在jvm参数中设置
java -Dreactor.netty.ioWorkerCount=2
2、使用原生的netty启动server,内部使用reactor-netty-client
查看Transport.java
/**
* Run IO loops on the given {@link EventLoopGroup}.
*
* @param eventLoopGroup an eventLoopGroup to share
* @return a new {@link Transport} reference
*/
public T runOn(EventLoopGroup eventLoopGroup) {
Objects.requireNonNull(eventLoopGroup, "eventLoopGroup");
return runOn(preferNative -> eventLoopGroup);
}
可以明确指定EventloopGroup,比如HttpClient场景
ConnectionProvider provider = ConnectionProvider.builder("name")
.pendingAcquireTimeout(Duration.ofSeconds(15))
.maxConnections(500).build();
EventLoopGroup group = new NioEventLoopGroup(3);
HttpClient client = HttpClient.create(provider).runOn(group);
int s = client.responseTimeout(Duration.ofSeconds(2))
.get()
.uri("http://127.0.0.1/remote")
.responseSingle((res, content) -> {
System.out.println(Thread.currentThread());
return Mono.just(res.status().code());
}).doOnError(t -> {
System.out.println("========error:" + t);
}).onErrorReturn(3)
.block();
System.out.println(s);
可以与其它地方定义好的eventLoopGroup共用, responseTimeout()针对单个请求还是全局呢?先来看一下方法说明:
/**
* Specifies the maximum duration allowed between each network-level read operation while reading a given response
* (resolution: ms). In other words, {@link io.netty.handler.timeout.ReadTimeoutHandler} is added to the channel
* pipeline after sending the request and is removed when the response is fully received.
* If the {@code maxReadOperationInterval} is {@code null}, any previous setting will be removed and no
* {@code maxReadOperationInterval} will be applied.
* If the {@code maxReadOperationInterval} is less than {@code 1ms}, then {@code 1ms} will be the
* {@code maxReadOperationInterval}.
* The {@code maxReadOperationInterval} setting on {@link HttpClientRequest} level overrides any
* {@code maxReadOperationInterval} setting on {@link HttpClient} level.
*
* @param maxReadOperationInterval the maximum duration allowed between each network-level read operations
* (resolution: ms).
* @return a new {@link HttpClient}
* @since 0.9.11
* @see io.netty.handler.timeout.ReadTimeoutHandler
*/
public final HttpClient responseTimeout(@Nullable Duration maxReadOperationInterval) {
if (Objects.equals(maxReadOperationInterval, configuration().responseTimeout)) {
return this;
}
HttpClient dup = duplicate();
dup.configuration().responseTimeout = maxReadOperationInterval;
return dup;
}
然后来实际验证一下:
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.create().responseTimeout(Duration.ofSeconds(5));
int s = client.responseTimeout(Duration.ofSeconds(2))
.get()
.uri("http://127.0.0.1:1701/abc")
.responseSingle((res, content) -> {
System.out.println(Thread.currentThread());
return Mono.just(res.status().code());
}).doOnError(t -> {
System.out.println("========error:" + t);
}).onErrorReturn(3)
.block();
System.out.println(s);
int s2 = client
.get()
.uri("http://127.0.0.1:1701/abc")
.responseSingle((res, content) -> {
System.out.println(Thread.currentThread());
return Mono.just(res.status().code());
}).doOnError(t -> {
System.out.println("========error:" + t);
}).onErrorReturn(3)
.block();
System.out.println(s2);
TimeUnit.SECONDS.sleep(10);
}
从实践中来看, 是全局的, 但也可以单次设置, 要注意源码中的一行HttpClient dup = duplicate();
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。