Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why always [reactor-tcp-nio-2] #65

Closed
1528110566 opened this issue Apr 13, 2023 · 4 comments
Closed

Why always [reactor-tcp-nio-2] #65

1528110566 opened this issue Apr 13, 2023 · 4 comments

Comments

@1528110566
Copy link

1528110566 commented Apr 13, 2023

I've created a new project, pom.xml is as follows

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>spring-boot-starter-parent</artifactId>
        <groupId>org.springframework.boot</groupId>
        <version>2.7.8</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>r2dbc-demo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-r2dbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mariadb</groupId>
            <artifactId>r2dbc-mariadb</artifactId>
        </dependency>
        <dependency>
            <groupId>io.r2dbc</groupId>
            <artifactId>r2dbc-spi</artifactId>
        </dependency>
        <dependency>
            <groupId>io.r2dbc</groupId>
            <artifactId>r2dbc-pool</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>
    </dependencies>
</project>

This controller gets me some data from DB, getTest retruns first record, getTest2 returns all records. There are about 10000 records in DB.

@RestController
public class TestController {
    @Autowired
    private R2dbcEntityTemplate template;

    @GetMapping("/test1")
    public Mono<Test> getTest() {
        return template.select(Test.class).first();
    }

    @GetMapping("/test2")
    public Flux<Test> getTest2() {
        return template.select(Test.class).all();
    }
}

application.yml

spring:
  r2dbc:
    url: r2dbc:mariadb://localhost:3306/r2dbc?userSSL=false
    username: root
    password: 123456
logging:
  level:
    root: trace

Here is my question, I request /test2 first, then /test1, /test1 will be wait until /test2 is complete.
log file shows that only 1 thread is handling my request, which is reactor-tcp-nio-2.
I tried to custom LoopResources, but I got the same result.
This problem has been bothering me for a long time. Could someone help me about it?
😭😭😭

@mp911de
Copy link

mp911de commented Apr 13, 2023

That's how netty dispatches connections across threads. This is not a problem, it is a consequence of the default EventExecutorChooser.

@1528110566
Copy link
Author

Sorry, I don't understand it clearly. Why not reactor-tcp-nio-1 to reactor-tcp-nio-n in circles?
I found this when I debug the code
reactor.netty.resources.ColocatedEventLoopGroup

@Override
public EventLoop next() {
	EventLoop loop = nextInternal();
	return loop != null ? loop : eventLoopGroup.next();
}

nextInternal() returns reactor-tcp-nio-2, and eventLoopGroup.next() won't be called forever.

@1528110566
Copy link
Author

1528110566 commented Apr 14, 2023

Here is my solution. I custom a NioEventLoopGroup instead of using ColocatedEventLoopGroup by default, and put it into runOn() function in SimpleClient.
Things looks normal for now.
But I still don't know why Netty using ColocatedEventLoopGroup by default and why the initialization of NioSocketChannel always under one same single thread(like reactor-tcp-nio-2).

@Bean
public ConnectionFactoryOptionsBuilderCustomizer customizer() {
    return builder -> {
        NioEventLoopGroup eventLoopGroup = new NioEventLoopGroup(6, new ThreadFactory() {
            private final AtomicInteger i = new AtomicInteger(0);
            @Override
            public Thread newThread(Runnable r) {
                Thread thread = new Thread(r);
                thread.setName("r2dbc-tcp-nio-" + i.getAndIncrement());
                return thread;
            }
        });
        LoopResources loopResources = useNative -> eventLoopGroup;
        builder.option(LOOP_RESOURCES, loopResources);
    };
}

@mp911de
Copy link

mp911de commented Apr 25, 2023

Leaving another reference: r2dbc/r2dbc-pool#190

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants