响应式编程实战:WebFlux与RSocket深度解析

引言

响应式编程正在重塑现代应用架构,从传统的同步阻塞模式转向异步非阻塞的响应式系统。Spring

WebFlux和RSocket为构建高性能、高并发的响应式应用提供了强大的工具集。本文将深入探讨响应式编程的核心概念,并通过实战案例展示如何构建真正的响应式系统。

响应式编程基础

1.1 Reactor核心概念

java 复制代码
// Reactor基础操作示例
@Component
@Slf4j
public class ReactorFundamentals {
    
    /**
     * Flux - 多个元素的异步序列
     */
    public Flux<String> createFluxExamples() {
        // 1. 从集合创建Flux
        Flux<String> fromIterable = Flux.fromIterable(Arrays.asList("A", "B", "C"));
        
        // 2. 从数组创建Flux
        Flux<String> fromArray = Flux.fromArray(new String[]{"X", "Y", "Z"});
        
        // 3. 使用just创建
        Flux<String> justFlux = Flux.just("Hello", "Reactive", "World");
        
        // 4. 使用range创建数值序列
        Flux<Integer> numberFlux = Flux.range(1, 10);
        
        // 5. 使用interval创建定时序列
        Flux<Long> intervalFlux = Flux.interval(Duration.ofSeconds(1))
            .take(5); // 只取前5个元素
            
        return justFlux;
    }
    
    /**
     * Mono - 单个元素的异步序列
     */
    public Mono<String> createMonoExamples() {
        // 1. 创建包含值的Mono
        Mono<String> justMono = Mono.just("Single Value");
        
        // 2. 创建空的Mono
        Mono<String> emptyMono = Mono.empty();
        
        // 3. 从Optional创建Mono
        Mono<String> fromOptional = Mono.justOrEmpty(Optional.of("Optional Value"));
        
        // 4. 从Callable创建Mono
        Mono<String> fromCallable = Mono.fromCallable(() -> {
            Thread.sleep(100); // 模拟耗时操作
            return "From Callable";
        });
        
        return justMono;
    }
    
    /**
     * 转换操作符
     */
    public Flux<String> transformationOperators() {
        return Flux.range(1, 5)
            .map(i -> "Number: " + i)                    // 同步转换
            .filter(s -> !s.contains("3"))              // 过滤
            .flatMap(s -> Mono.just(s + "!"))           // 异步转换
            .concatWith(Flux.just("Final Item"))        // 连接流
            .distinct()                                  // 去重
            .take(3)                                     // 取前N个
            .skip(1)                                     // 跳过前N个
            .doOnNext(item -> log.info("Processing: {}", item)) // 副作用
            .doOnComplete(() -> log.info("Stream completed"));
    }
    
    /**
     * 组合操作符
     */
    public Flux<String> combinationOperators() {
        Flux<String> first = Flux.just("A", "B", "C");
        Flux<String> second = Flux.just("X", "Y", "Z");
        
        // 1. merge - 合并流(交错发射)
        Flux<String> merged = Flux.merge(first, second);
        
        // 2. zip - 配对合并
        Flux<String> zipped = Flux.zip(first, second, 
            (f, s) -> f + "-" + s);
            
        // 3. concat - 顺序连接
        Flux<String> concatenated = Flux.concat(first, second);
        
        // 4. combineLatest - 组合最新值
        Flux<Long> tick1 = Flux.interval(Duration.ofMillis(800));
        Flux<Long> tick2 = Flux.interval(Duration.ofMillis(1000));
        Flux<String> combined = Flux.combineLatest(tick1, tick2, 
            (t1, t2) -> t1 + ":" + t2);
            
        return zipped.take(3);
    }
    
    /**
     * 错误处理操作符
     */
    public Flux<String> errorHandlingOperators() {
        return Flux.range(1, 5)
            .map(i -> {
                if (i == 3) {
                    throw new RuntimeException("Error at " + i);
                }
                return "Item " + i;
            })
            .onErrorReturn("Fallback Value")                    // 返回默认值
            .onErrorResume(error -> {                          // 恢复为另一个流
                log.error("Error occurred: {}", error.getMessage());
                return Flux.just("Recovery Item 1", "Recovery Item 2");
            })
            .retry(2)                                          // 重试2次
            .doOnError(error -> log.error("Final error: {}", error.getMessage()));
    }
    
    /**
     * 背压处理
     */
    public Flux<Integer> backpressureHandling() {
        return Flux.range(1, 1000)
            .onBackpressureBuffer(50, // 缓冲区大小
                buffer -> log.warn("Buffer overflow: {}", buffer),
                BufferOverflowStrategy.DROP_LATEST)
            .onBackpressureDrop(dropped -> 
                log.warn("Dropped due to backpressure: {}", dropped))
            .doOnNext(item -> {
                // 模拟处理延迟
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            });
    }
    
    /**
     * 调度器使用
     */
    public Flux<String> schedulerExamples() {
        return Flux.range(1, 10)
            .publishOn(Schedulers.parallel())           // 后续操作在并行线程执行
            .map(i -> {
                log.info("Processing {} on thread: {}", i, 
                    Thread.currentThread().getName());
                return "Processed: " + i;
            })
            .subscribeOn(Schedulers.boundedElastic())   // 订阅在弹性线程池执行
            .doOnSubscribe(subscription -> 
                log.info("Subscribed on thread: {}", Thread.currentThread().getName()));
    }
    
    /**
     * 热序列 vs 冷序列
     */
    public void hotVsColdSequences() {
        // 冷序列 - 每个订阅者都会收到完整的数据
        Flux<String> coldFlux = Flux.defer(() -> {
            log.info("Creating new data stream");
            return Flux.just("Cold", "Data", "Stream");
        });
        
        // 热序列 - 数据独立于订阅者
        ConnectableFlux<String> hotFlux = Flux.interval(Duration.ofSeconds(1))
            .map(i -> "Hot Data " + i)
            .publish(); // 转换为热序列
            
        hotFlux.connect(); // 开始发射数据
        
        // 第一个订阅者
        hotFlux.subscribe(data -> log.info("Subscriber 1: {}", data));
        
        // 2秒后第二个订阅者加入
        new Thread(() -> {
            try {
                Thread.sleep(2000);
                hotFlux.subscribe(data -> log.info("Subscriber 2: {}", data));
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }).start();
    }
}

1.2 响应式编程模式

java 复制代码
// 响应式设计模式
@Component
@Slf4j
public class ReactivePatterns {
    
    /**
     * 异步流水线模式
     */
    public Mono<String> asyncPipeline(String input) {
        return Mono.just(input)
            .publishOn(Schedulers.parallel())
            .map(this::validateInput)
            .flatMap(this::processData)
            .publishOn(Schedulers.boundedElastic())
            .flatMap(this::saveToDatabase)
            .publishOn(Schedulers.parallel())
            .map(this::formatResponse)
            .onErrorResume(this::handleError);
    }
    
    private String validateInput(String input) {
        if (input == null || input.trim().isEmpty()) {
            throw new IllegalArgumentException("Input cannot be empty");
        }
        return input.trim();
    }
    
    private Mono<String> processData(String data) {
        return Mono.fromCallable(() -> {
            // 模拟耗时处理
            Thread.sleep(100);
            return data.toUpperCase();
        }).subscribeOn(Schedulers.boundedElastic());
    }
    
    private Mono<String> saveToDatabase(String data) {
        // 模拟数据库操作
        return Mono.just("saved:" + data)
            .delayElement(Duration.ofMillis(50))
            .doOnNext(result -> log.info("Saved to database: {}", result));
    }
    
    private String formatResponse(String data) {
        return "Response: " + data;
    }
    
    private Mono<String> handleError(Throwable error) {
        log.error("Pipeline error: {}", error.getMessage());
        return Mono.just("Error: " + error.getMessage());
    }
    
    /**
     * 请求-响应模式
     */
    public Mono<UserProfile> requestResponsePattern(Long userId) {
        return getUserById(userId)
            .flatMap(user -> getProfileByUser(user))
            .timeout(Duration.ofSeconds(5))
            .retryWhen(Retry.backoff(3, Duration.ofMillis(100)));
    }
    
    private Mono<User> getUserById(Long userId) {
        return Mono.just(new User(userId, "user" + userId))
            .delayElement(Duration.ofMillis(100));
    }
    
    private Mono<UserProfile> getProfileByUser(User user) {
        return Mono.just(new UserProfile(user, "profile@" + user.getName()))
            .delayElement(Duration.ofMillis(150));
    }
    
    /**
     * 事件总线模式
     */
    public static class ReactiveEventBus {
        private final Sinks.Many<Event> eventSink = Sinks.many().multicast().onBackpressureBuffer();
        private final Flux<Event> eventFlux = eventSink.asFlux().publish().autoConnect();
        
        public void publishEvent(Event event) {
            eventSink.tryEmitNext(event);
        }
        
        public <T extends Event> Flux<T> subscribe(Class<T> eventType) {
            return eventFlux
                .filter(eventType::isInstance)
                .cast(eventType)
                .onBackpressureLatest();
        }
    }
    
    /**
     * 缓存模式
     */
    public static class ReactiveCache<K, V> {
        private final Map<K, Mono<V>> cache = new ConcurrentHashMap<>();
        private final Function<K, Mono<V>> valueLoader;
        
        public ReactiveCache(Function<K, Mono<V>> valueLoader) {
            this.valueLoader = valueLoader;
        }
        
        public Mono<V> get(K key) {
            return cache.computeIfAbsent(key, k -> 
                valueLoader.apply(k)
                    .cache(Duration.ofMinutes(10)) // 缓存10分钟
                    .doOnError(error -> cache.remove(key)) // 错误时移除缓存
            );
        }
        
        public void evict(K key) {
            cache.remove(key);
        }
    }
    
    /**
     * 批量处理模式
     */
    public static class BatchProcessor<T> {
        private final Sinks.Many<T> sink = Sinks.many().unicast().onBackpressureBuffer();
        private final Flux<List<T>> batchedFlux;
        
        public BatchProcessor(int batchSize, Duration windowTimeout) {
            this.batchedFlux = sink.asFlux()
                .windowTimeout(batchSize, windowTimeout)
                .flatMap(window -> window.collectList())
                .publish()
                .autoConnect();
        }
        
        public void addItem(T item) {
            sink.tryEmitNext(item);
        }
        
        public Flux<List<T>> getBatches() {
            return batchedFlux;
        }
    }
    
    // 领域模型
    static class User {
        private final Long id;
        private final String name;
        
        User(Long id, String name) {
            this.id = id;
            this.name = name;
        }
        
        public Long getId() { return id; }
        public String getName() { return name; }
    }
    
    static class UserProfile {
        private final User user;
        private final String email;
        
        UserProfile(User user, String email) {
            this.user = user;
            this.email = email;
        }
        
        public User getUser() { return user; }
        public String getEmail() { return email; }
    }
    
    static class Event {
        private final String type;
        private final Object data;
        
        Event(String type, Object data) {
            this.type = type;
            this.data = data;
        }
        
        public String getType() { return type; }
        public Object getData() { return data; }
    }
}

Spring WebFlux深度实战

2.1 WebFlux控制器与路由

java 复制代码
// 响应式REST控制器
@RestController
@RequestMapping("/api/reactive/users")
@Slf4j
public class ReactiveUserController {
    
    private final ReactiveUserService userService;
    private final ReactiveEventPublisher eventPublisher;
    
    public ReactiveUserController(ReactiveUserService userService, 
                                 ReactiveEventPublisher eventPublisher) {
        this.userService = userService;
        this.eventPublisher = eventPublisher;
    }
    
    /**
     * 获取所有用户 - 流式响应
     */
    @GetMapping(produces = MediaType.APPLICATION_NDJSON_VALUE)
    public Flux<UserDTO> getAllUsers(
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "20") int size) {
        
        return userService.findAllUsers(page, size)
            .doOnSubscribe(s -> log.info("开始流式返回用户数据"))
            .doOnComplete(() -> log.info("用户数据流完成"))
            .doOnError(error -> log.error("用户数据流错误", error));
    }
    
    /**
     * 根据ID获取用户
     */
    @GetMapping("/{id}")
    public Mono<ResponseEntity<UserDTO>> getUserById(@PathVariable Long id) {
        return userService.findUserById(id)
            .map(user -> ResponseEntity.ok(user))
            .defaultIfEmpty(ResponseEntity.notFound().build())
            .doOnSuccess(response -> {
                if (response.getStatusCode().is2xxSuccessful()) {
                    log.info("成功获取用户: {}", id);
                } else {
                    log.warn("用户不存在: {}", id);
                }
            });
    }
    
    /**
     * 创建用户
     */
    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public Mono<UserDTO> createUser(@Valid @RequestBody Mono<CreateUserRequest> request) {
        return request
            .flatMap(userService::createUser)
            .doOnSuccess(user -> {
                log.info("创建用户成功: {}", user.getId());
                eventPublisher.publishUserCreated(user);
            })
            .doOnError(error -> log.error("创建用户失败", error));
    }
    
    /**
     * 更新用户
     */
    @PutMapping("/{id}")
    public Mono<ResponseEntity<UserDTO>> updateUser(
            @PathVariable Long id,
            @Valid @RequestBody Mono<UpdateUserRequest> request) {
        
        return request
            .flatMap(updateRequest -> userService.updateUser(id, updateRequest))
            .map(updatedUser -> ResponseEntity.ok(updatedUser))
            .defaultIfEmpty(ResponseEntity.notFound().build());
    }
    
    /**
     * 删除用户
     */
    @DeleteMapping("/{id}")
    public Mono<ResponseEntity<Void>> deleteUser(@PathVariable Long id) {
        return userService.deleteUser(id)
            .then(Mono.just(ResponseEntity.noContent().build()))
            .onErrorReturn(ResponseEntity.notFound().build());
    }
    
    /**
     * 搜索用户 - Server-Sent Events
     */
    @GetMapping(value = "/search", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<UserDTO> searchUsers(
            @RequestParam String keyword,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "20") int size) {
        
        return userService.searchUsers(keyword, page, size)
            .delayElements(Duration.ofMillis(100)) // 控制发射速度
            .doOnNext(user -> log.debug("发送用户: {}", user.getName()));
    }
    
    /**
     * 用户统计信息
     */
    @GetMapping("/stats")
    public Mono<Map<String, Object>> getUserStats() {
        return userService.getUserStatistics()
            .doOnSubscribe(s -> log.info("获取用户统计信息"));
    }
    
    /**
     * 批量创建用户
     */
    @PostMapping("/batch")
    public Flux<UserDTO> createUsersBatch(@Valid @RequestBody Flux<CreateUserRequest> requests) {
        return requests
            .buffer(10) // 每10个请求批量处理
            .delayElements(Duration.ofMillis(500)) // 控制处理速度
            .flatMap(batch -> userService.createUsersBatch(Flux.fromIterable(batch)))
            .doOnNext(user -> log.info("批量创建用户: {}", user.getId()));
    }
}

// 函数式路由配置
@Configuration
@Slf4j
public class FunctionalRoutesConfiguration {
    
    @Bean
    public RouterFunction<ServerResponse> userRoutes(ReactiveUserHandler userHandler) {
        return RouterFunctions.route()
            .GET("/api/v2/users", userHandler::getAllUsers)
            .GET("/api/v2/users/{id}", userHandler::getUserById)
            .POST("/api/v2/users", userHandler::createUser)
            .PUT("/api/v2/users/{id}", userHandler::updateUser)
            .DELETE("/api/v2/users/{id}", userHandler::deleteUser)
            .GET("/api/v2/users/{id}/events", userHandler::getUserEvents)
            .add(otherRoutes())
            .filter(authenticationFilter())
            .filter(loggingFilter())
            .build();
    }
    
    @Bean
    public RouterFunction<ServerResponse> otherRoutes() {
        return RouterFunctions.route()
            .GET("/api/v2/health", request -> 
                ServerResponse.ok().bodyValue(Map.of("status", "UP")))
            .GET("/api/v2/metrics", this::getMetrics)
            .build();
    }
    
    private Mono<ServerResponse> getMetrics(ServerRequest request) {
        return ServerResponse.ok()
            .contentType(MediaType.APPLICATION_JSON)
            .body(BodyInserters.fromValue(Map.of(
                "activeConnections", 150,
                "memoryUsage", "65%",
                "responseTime", "45ms"
            )));
    }
    
    // 认证过滤器
    private HandlerFilterFunction<ServerResponse, ServerResponse> authenticationFilter() {
        return (request, next) -> {
            String authHeader = request.headers().firstHeader("Authorization");
            if (authHeader == null || !authHeader.startsWith("Bearer ")) {
                return ServerResponse.status(HttpStatus.UNAUTHORIZED).build();
            }
            return next.handle(request);
        };
    }
    
    // 日志过滤器
    private HandlerFilterFunction<ServerResponse, ServerResponse> loggingFilter() {
        return (request, next) -> {
            long startTime = System.currentTimeMillis();
            return next.handle(request)
                .doOnNext(response -> {
                    long duration = System.currentTimeMillis() - startTime;
                    log.info("{} {} - {} - {}ms", 
                        request.method(), 
                        request.path(),
                        response.statusCode(),
                        duration);
                });
        };
    }
}

// 函数式处理器
@Component
@Slf4j
public class ReactiveUserHandler {
    
    private final ReactiveUserService userService;
    private final ObjectMapper objectMapper;
    
    public ReactiveUserHandler(ReactiveUserService userService, ObjectMapper objectMapper) {
        this.userService = userService;
        this.objectMapper = objectMapper;
    }
    
    public Mono<ServerResponse> getAllUsers(ServerRequest request) {
        int page = Integer.parseInt(request.queryParam("page").orElse("0"));
        int size = Integer.parseInt(request.queryParam("size").orElse("20"));
        
        return userService.findAllUsers(page, size)
            .collectList()
            .flatMap(users -> ServerResponse.ok()
                .contentType(MediaType.APPLICATION_JSON)
                .bodyValue(users));
    }
    
    public Mono<ServerResponse> getUserById(ServerRequest request) {
        Long id = Long.parseLong(request.pathVariable("id"));
        
        return userService.findUserById(id)
            .flatMap(user -> ServerResponse.ok()
                .contentType(MediaType.APPLICATION_JSON)
                .bodyValue(user))
            .switchIfEmpty(ServerResponse.notFound().build());
    }
    
    public Mono<ServerResponse> createUser(ServerRequest request) {
        return request.bodyToMono(CreateUserRequest.class)
            .flatMap(userService::createUser)
            .flatMap(user -> ServerResponse.status(HttpStatus.CREATED)
                .contentType(MediaType.APPLICATION_JSON)
                .bodyValue(user))
            .onErrorResume(ValidationException.class, e -> 
                ServerResponse.badRequest()
                    .bodyValue(Map.of("error", e.getMessage())));
    }
    
    public Mono<ServerResponse> updateUser(ServerRequest request) {
        Long id = Long.parseLong(request.pathVariable("id"));
        
        return request.bodyToMono(UpdateUserRequest.class)
            .flatMap(updateRequest -> userService.updateUser(id, updateRequest))
            .flatMap(user -> ServerResponse.ok()
                .contentType(MediaType.APPLICATION_JSON)
                .bodyValue(user))
            .switchIfEmpty(ServerResponse.notFound().build());
    }
    
    public Mono<ServerResponse> deleteUser(ServerRequest request) {
        Long id = Long.parseLong(request.pathVariable("id"));
        
        return userService.deleteUser(id)
            .then(ServerResponse.noContent().build())
            .switchIfEmpty(ServerResponse.notFound().build());
    }
    
    public Mono<ServerResponse> getUserEvents(ServerRequest request) {
        Long id = Long.parseLong(request.pathVariable("id"));
        
        return ServerResponse.ok()
            .contentType(MediaType.TEXT_EVENT_STREAM)
            .body(userService.getUserEvents(id), UserEvent.class);
    }
}

2.2 WebFlux高级特性

java 复制代码
// WebFlux配置与优化
@Configuration
@EnableWebFlux
@Slf4j
public class WebFluxConfiguration implements WebFluxConfigurer {
    
    @Override
    public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
        // 配置消息编解码器
        configurer.defaultCodecs().maxInMemorySize(10 * 1024 * 1024); // 10MB
    }
    
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        // 配置CORS
        registry.addMapping("/api/**")
            .allowedOrigins("https://example.com")
            .allowedMethods("GET", "POST", "PUT", "DELETE")
            .allowedHeaders("*")
            .allowCredentials(true);
    }
    
    @Bean
    public WebExceptionHandler webExceptionHandler() {
        // 全局异常处理
        return (exchange, ex) -> {
            ServerHttpResponse response = exchange.getResponse();
            
            if (ex instanceof ValidationException) {
                response.setStatusCode(HttpStatus.BAD_REQUEST);
                return response.writeWith(Mono.just(response.bufferFactory()
                    .wrap(createErrorResponse(ex.getMessage()).getBytes())));
            }
            
            if (ex instanceof NotFoundException) {
                response.setStatusCode(HttpStatus.NOT_FOUND);
                return response.writeWith(Mono.just(response.bufferFactory()
                    .wrap(createErrorResponse("Resource not found").getBytes())));
            }
            
            log.error("Unhandled exception", ex);
            response.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
            return response.writeWith(Mono.just(response.bufferFactory()
                .wrap(createErrorResponse("Internal server error").getBytes())));
        };
    }
    
    private String createErrorResponse(String message) {
        return "{\"error\": \"" + message + "\"}";
    }
    
    @Bean
    public WebFilter contextLoggingFilter() {
        // 上下文日志过滤器
        return (exchange, chain) -> {
            String requestId = UUID.randomUUID().toString();
            exchange.getAttributes().put("requestId", requestId);
            
            long startTime = System.currentTimeMillis();
            
            return chain.filter(exchange)
                .doOnSuccessOrError((v, e) -> {
                    long duration = System.currentTimeMillis() - startTime;
                    ServerHttpRequest request = exchange.getRequest();
                    ServerHttpResponse response = exchange.getResponse();
                    
                    log.info("Request completed: {} {} - {} - {}ms - requestId: {}", 
                        request.getMethod(), 
                        request.getPath(),
                        response.getStatusCode(),
                        duration,
                        requestId);
                });
        };
    }
    
    @Bean
    public WebFilter rateLimitingFilter() {
        // 简单的速率限制过滤器
        return (exchange, chain) -> {
            String clientIp = getClientIp(exchange.getRequest());
            
            // 这里可以实现更复杂的速率限制逻辑
            if (isRateLimited(clientIp)) {
                return Mono.fromRunnable(() -> {
                    ServerHttpResponse response = exchange.getResponse();
                    response.setStatusCode(HttpStatus.TOO_MANY_REQUESTS);
                });
            }
            
            return chain.filter(exchange);
        };
    }
    
    private String getClientIp(ServerHttpRequest request) {
        String xForwardedFor = request.getHeaders().getFirst("X-Forwarded-For");
        if (xForwardedFor != null && !xForwardedFor.isEmpty()) {
            return xForwardedFor.split(",")[0].trim();
        }
        return request.getRemoteAddress() != null ? 
            request.getRemoteAddress().getAddress().getHostAddress() : "unknown";
    }
    
    private boolean isRateLimited(String clientIp) {
        // 实现速率限制逻辑
        return false;
    }
}

// 响应式服务实现
@Service
@Slf4j
public class ReactiveUserService {
    
    private final ReactiveUserRepository userRepository;
    private final ReactiveProfileService profileService;
    private final ReactiveEventPublisher eventPublisher;
    private final Sinks.Many<UserEvent> userEventSink;
    
    public ReactiveUserService(ReactiveUserRepository userRepository,
                              ReactiveProfileService profileService,
                              ReactiveEventPublisher eventPublisher) {
        this.userRepository = userRepository;
        this.profileService = profileService;
        this.eventPublisher = eventPublisher;
        this.userEventSink = Sinks.many().multicast().onBackpressureBuffer();
    }
    
    /**
     * 查找所有用户 - 分页支持
     */
    public Flux<UserDTO> findAllUsers(int page, int size) {
        return userRepository.findAll()
            .skip(page * size)
            .take(size)
            .map(this::convertToDTO)
            .doOnRequest(n -> log.debug("Requested {} users", n));
    }
    
    /**
     * 根据ID查找用户 - 包含Profile信息
     */
    public Mono<UserDTO> findUserById(Long id) {
        return userRepository.findById(id)
            .map(this::convertToDTO)
            .flatMap(user -> profileService.findProfileByUserId(id)
                .map(profile -> {
                    user.setProfile(profile);
                    return user;
                })
                .defaultIfEmpty(user))
            .doOnSuccess(user -> {
                if (user != null) {
                    log.debug("Found user: {}", user.getName());
                }
            });
    }
    
    /**
     * 创建用户 - 事务性操作
     */
    @Transactional
    public Mono<UserDTO> createUser(CreateUserRequest request) {
        return Mono.just(request)
            .map(this::convertToEntity)
            .flatMap(userRepository::save)
            .map(this::convertToDTO)
            .flatMap(user -> profileService.createProfile(user.getId(), request.getEmail())
                .thenReturn(user))
            .doOnSuccess(user -> {
                log.info("User created successfully: {}", user.getId());
                eventPublisher.publishUserCreated(user);
                userEventSink.tryEmitNext(new UserEvent("USER_CREATED", user));
            })
            .doOnError(error -> log.error("Failed to create user", error));
    }
    
    /**
     * 批量创建用户
     */
    public Flux<UserDTO> createUsersBatch(Flux<CreateUserRequest> requests) {
        return requests
            .map(this::convertToEntity)
            .buffer(10) // 批量保存
            .flatMap(userRepository::saveAll)
            .map(this::convertToDTO)
            .doOnNext(user -> log.info("Batch created user: {}", user.getId()));
    }
    
    /**
     * 搜索用户
     */
    public Flux<UserDTO> searchUsers(String keyword, int page, int size) {
        return userRepository.findByNameContainingIgnoreCase(keyword)
            .skip(page * size)
            .take(size)
            .map(this::convertToDTO)
            .doOnSubscribe(s -> log.info("Searching users with keyword: {}", keyword));
    }
    
    /**
     * 获取用户事件流
     */
    public Flux<UserEvent> getUserEvents(Long userId) {
        return userEventSink.asFlux()
            .filter(event -> event.getUser().getId().equals(userId))
            .doOnSubscribe(s -> log.info("User {} subscribed to events", userId));
    }
    
    /**
     * 获取用户统计信息
     */
    public Mono<Map<String, Object>> getUserStatistics() {
        return userRepository.count()
            .zipWith(userRepository.countActiveUsers())
            .map(tuple -> Map.of(
                "totalUsers", tuple.getT1(),
                "activeUsers", tuple.getT2(),
                "timestamp", Instant.now()
            ));
    }
    
    /**
     * 更新用户信息
     */
    public Mono<UserDTO> updateUser(Long id, UpdateUserRequest request) {
        return userRepository.findById(id)
            .flatMap(user -> {
                user.setName(request.getName());
                user.setEmail(request.getEmail());
                user.setUpdatedAt(Instant.now());
                return userRepository.save(user);
            })
            .map(this::convertToDTO)
            .doOnSuccess(user -> {
                log.info("User updated: {}", id);
                userEventSink.tryEmitNext(new UserEvent("USER_UPDATED", user));
            })
            .switchIfEmpty(Mono.error(new NotFoundException("User not found: " + id)));
    }
    
    /**
     * 删除用户
     */
    public Mono<Void> deleteUser(Long id) {
        return userRepository.findById(id)
            .flatMap(user -> userRepository.delete(user))
            .doOnSuccess(v -> {
                log.info("User deleted: {}", id);
                userEventSink.tryEmitNext(new UserEvent("USER_DELETED", 
                    new UserDTO(id, "deleted", null)));
            })
            .switchIfEmpty(Mono.error(new NotFoundException("User not found: " + id)));
    }
    
    private User convertToEntity(CreateUserRequest request) {
        User user = new User();
        user.setName(request.getName());
        user.setEmail(request.getEmail());
        user.setCreatedAt(Instant.now());
        user.setActive(true);
        return user;
    }
    
    private UserDTO convertToDTO(User user) {
        return new UserDTO(user.getId(), user.getName(), user.getEmail());
    }
}

RSocket深度实战

3.1 RSocket通信模式

java 复制代码
// RSocket服务端配置
@Configuration
@Slf4j
@MessageMapping("user.service")
public class RSocketServerConfiguration {
    
    private final ReactiveUserService userService;
    
    public RSocketServerConfiguration(ReactiveUserService userService) {
        this.userService = userService;
    }
    
    /**
     * 请求-响应模式 (Request-Response)
     */
    @MessageMapping("user.get")
    public Mono<UserDTO> getUser(Message<Long> message) {
        Long userId = message.getPayload();
        log.info("RSocket request-response: Get user {}", userId);
        
        return userService.findUserById(userId)
            .doOnSuccess(user -> log.debug("Found user: {}", user.getName()))
            .doOnError(error -> log.error("Error getting user: {}", userId, error));
    }
    
    /**
     * 请求-流模式 (Request-Stream)
     */
    @MessageMapping("users.stream")
    public Flux<UserDTO> streamUsers(Message<Map<String, Object>> message) {
        Map<String, Object> params = message.getPayload();
        int page = (int) params.getOrDefault("page", 0);
        int size = (int) params.getOrDefault("size", 10);
        
        log.info("RSocket request-stream: Stream users page={}, size={}", page, size);
        
        return userService.findAllUsers(page, size)
            .doOnSubscribe(s -> log.debug("Starting user stream"))
            .doOnNext(user -> log.trace("Streaming user: {}", user.getName()))
            .doOnComplete(() -> log.debug("User stream completed"))
            .doOnError(error -> log.error("User stream error", error));
    }
    
    /**
     * 即发-忘模式 (Fire-and-Forget)
     */
    @MessageMapping("user.update.lastSeen")
    public Mono<Void> updateLastSeen(Message<UserActivity> message) {
        UserActivity activity = message.getPayload();
        log.info("RSocket fire-and-forget: Update last seen for user {}", activity.getUserId());
        
        // 异步处理,不等待响应
        return userService.updateLastSeen(activity.getUserId(), activity.getTimestamp())
            .doOnSuccess(v -> log.debug("Last seen updated for user {}", activity.getUserId()))
            .doOnError(error -> log.error("Failed to update last seen", error))
            .onErrorResume(error -> Mono.empty()); // 忽略错误
    }
    
    /**
     * 通道模式 (Channel)
     */
    @MessageMapping("user.events.channel")
    public Flux<UserEvent> userEventsChannel(Flux<Map<String, Object>> requests) {
        log.info("RSocket channel: User events channel established");
        
        return requests
            .switchMap(params -> {
                Long userId = (Long) params.get("userId");
                String eventType = (String) params.get("eventType");
                
                log.debug("Channel request: userId={}, eventType={}", userId, eventType);
                
                if ("ALL".equals(eventType)) {
                    return userService.getUserEvents(userId);
                } else {
                    return userService.getUserEvents(userId)
                        .filter(event -> event.getType().equals(eventType));
                }
            })
            .doOnSubscribe(s -> log.debug("User events channel subscribed"))
            .doOnNext(event -> log.trace("Sending event: {}", event.getType()))
            .doOnComplete(() -> log.debug("User events channel completed"))
            .doOnError(error -> log.error("User events channel error", error));
    }
    
    /**
     * 元数据推送
     */
    @MessageMapping("user.metadata")
    public Mono<Map<String, Object>> getUserWithMetadata(Message<Long> message) {
        Long userId = message.getPayload();
        
        // 处理元数据
        MimeType mimeType = message.getHeaders().getContentType();
        log.info("Request with metadata: contentType={}", mimeType);
        
        return userService.findUserById(userId)
            .map(user -> {
                Map<String, Object> response = new HashMap<>();
                response.put("user", user);
                response.put("metadata", Map.of(
                    "processedAt", Instant.now(),
                    "serverId", "user-service-1"
                ));
                return response;
            });
    }
}

// RSocket客户端服务
@Service
@Slf4j
public class RSocketClientService {
    
    private final RSocketRequester rSocketRequester;
    private final ObjectMapper objectMapper;
    
    public RSocketClientService(RSocketRequester.Builder builder, ObjectMapper objectMapper) {
        this.rSocketRequester = builder
            .setupRoute("client.connect")
            .setupData(Map.of("clientId", "web-client", "version", "1.0"))
            .tcp("localhost", 7000);
        this.objectMapper = objectMapper;
    }
    
    /**
     * 请求-响应模式调用
     */
    public Mono<UserDTO> getUserById(Long userId) {
        log.info("RSocket client request-response: Get user {}", userId);
        
        return rSocketRequester
            .route("user.service.user.get")
            .data(userId)
            .retrieveMono(UserDTO.class)
            .timeout(Duration.ofSeconds(5))
            .doOnSuccess(user -> log.debug("Received user: {}", user.getName()))
            .doOnError(error -> log.error("Failed to get user: {}", userId, error));
    }
    
    /**
     * 请求-流模式调用
     */
    public Flux<UserDTO> streamUsers(int page, int size) {
        log.info("RSocket client request-stream: Stream users page={}, size={}", page, size);
        
        Map<String, Object> params = Map.of("page", page, "size", size);
        
        return rSocketRequester
            .route("user.service.users.stream")
            .data(params)
            .retrieveFlux(UserDTO.class)
            .doOnSubscribe(s -> log.debug("Starting user stream"))
            .doOnNext(user -> log.trace("Received user: {}", user.getName()))
            .doOnComplete(() -> log.debug("User stream completed"))
            .doOnError(error -> log.error("User stream error", error));
    }
    
    /**
     * 即发-忘模式调用
     */
    public Mono<Void> updateUserLastSeen(Long userId) {
        log.info("RSocket client fire-and-forget: Update last seen for user {}", userId);
        
        UserActivity activity = new UserActivity(userId, Instant.now());
        
        return rSocketRequester
            .route("user.service.user.update.lastSeen")
            .data(activity)
            .send()
            .doOnSuccess(v -> log.debug("Last seen update sent for user {}", userId))
            .doOnError(error -> log.error("Failed to send last seen update", error));
    }
    
    /**
     * 通道模式调用
     */
    public Flux<UserEvent> openUserEventsChannel(Long userId, String eventType) {
        log.info("RSocket client channel: Open events channel for user {}, eventType={}", 
            userId, eventType);
        
        Map<String, Object> initialRequest = Map.of(
            "userId", userId,
            "eventType", eventType
        );
        
        return rSocketRequester
            .route("user.service.user.events.channel")
            .data(Flux.interval(Duration.ofMinutes(1))
                .map(i -> Map.of("userId", userId, "eventType", eventType)))
            .retrieveFlux(UserEvent.class)
            .doOnSubscribe(s -> log.debug("User events channel opened"))
            .doOnNext(event -> log.debug("Received event: {}", event.getType()))
            .doOnComplete(() -> log.debug("User events channel closed"))
            .doOnError(error -> log.error("User events channel error", error));
    }
    
    /**
     * 负载均衡调用
     */
    public Mono<UserDTO> getUserWithLoadBalancing(Long userId) {
        return rSocketRequester
            .route("user.service.user.get")
            .data(userId)
            .retrieveMono(UserDTO.class)
            .onErrorResume(error -> {
                log.warn("Primary service failed, trying backup: {}", error.getMessage());
                // 可以切换到备份服务
                return getBackupUser(userId);
            });
    }
    
    private Mono<UserDTO> getBackupUser(Long userId) {
        // 实现备份服务调用
        return Mono.just(new UserDTO(userId, "backup-user", "backup@example.com"));
    }
    
    /**
     * 带元数据的调用
     */
    public Mono<Map<String, Object>> getUserWithMetadata(Long userId) {
        return rSocketRequester
            .route("user.service.user.metadata")
            .metadata("client-timestamp", Instant.now().toString())
            .data(userId)
            .retrieveMono(Map.class)
            .doOnSuccess(response -> {
                log.debug("Received response with metadata: {}", response.get("metadata"));
            });
    }
}

// RSocket配置
@Configuration
@Slf4j
public class RSocketConfiguration {
    
    @Bean
    public RSocketStrategies rSocketStrategies() {
        return RSocketStrategies.builder()
            .encoders(encoders -> encoders.add(new Jackson2CborEncoder()))
            .decoders(decoders -> decoders.add(new Jackson2CborDecoder()))
            .routeMatcher(new PathPatternRouteMatcher())
            .metadataExtractor(metadataExtractor())
            .build();
    }
    
    @Bean
    public MetadataExtractor metadataExtractor() {
        return new DefaultMetadataExtractor();
    }
    
    @Bean
    public RSocketMessageHandler rSocketMessageHandler(RSocketStrategies strategies) {
        RSocketMessageHandler handler = new RSocketMessageHandler();
        handler.setRSocketStrategies(strategies);
        return handler;
    }
    
    @Bean
    @Profile("rsocket-server")
    public RSocketServerCustomizer rSocketServerCustomizer() {
        return server -> server
            .fragment(16384) // 16KB fragments
            .payloadDecoder(PayloadDecoder.ZERO_COPY);
    }
    
    @Bean
    @Profile("rsocket-client")
    public RSocketRequester rSocketRequester(RSocketRequester.Builder builder) {
        return builder
            .rsocketConnector(connector -> connector
                .reconnect(Retry.fixedDelay(3, Duration.ofSeconds(2)))
            .tcp("localhost", 7000);
    }
}

// 领域模型
@Data
@AllArgsConstructor
@NoArgsConstructor
class UserActivity {
    private Long userId;
    private Instant timestamp;
}

@Data
@AllArgsConstructor
@NoArgsConstructor
class UserEvent {
    private String type;
    private UserDTO user;
    private Instant timestamp = Instant.now();
}

@Data
@AllArgsConstructor
@NoArgsConstructor
class CreateUserRequest {
    @NotBlank
    private String name;
    
    @Email
    private String email;
}

@Data
@AllArgsConstructor
@NoArgsConstructor  
class UpdateUserRequest {
    @NotBlank
    private String name;
    
    @Email
    private String email;
}

@Data
@AllArgsConstructor
@NoArgsConstructor
class UserDTO {
    private Long id;
    private String name;
    private String email;
    private Object profile;
    
    public UserDTO(Long id, String name, String email) {
        this.id = id;
        this.name = name;
        this.email = email;
    }
}

// 自定义异常
class ValidationException extends RuntimeException {
    public ValidationException(String message) {
        super(message);
    }
}

class NotFoundException extends RuntimeException {
    public NotFoundException(String message) {
        super(message);
    }
}

性能优化与监控

4.1 响应式应用性能调优

java 复制代码
// 响应式性能监控
@Component
@Slf4j
public class ReactivePerformanceMonitor {
    
    private final MeterRegistry meterRegistry;
    private final Timer webfluxRequestTimer;
    private final Counter backpressureEvents;
    private final Gauge activeSubscriptions;
    
    private final AtomicInteger subscriptionCount = new AtomicInteger(0);
    
    public ReactivePerformanceMonitor(MeterRegistry meterRegistry) {
        this.meterRegistry = meterRegistry;
        
        this.webfluxRequestTimer = Timer.builder("webflux.request.duration")
            .description("WebFlux request processing duration")
            .register(meterRegistry);
            
        this.backpressureEvents = Counter.builder("reactive.backpressure.events")
            .description("Backpressure events count")
            .register(meterRegistry);
            
        this.activeSubscriptions = Gauge.builder("reactive.subscriptions.active")
            .description("Active reactive subscriptions")
            .register(meterRegistry, subscriptionCount, AtomicInteger::get);
    }
    
    /**
     * 监控Flux性能
     */
    public <T> Flux<T> monitorFlux(String name, Flux<T> flux) {
        return flux
            .doOnSubscribe(s -> {
                subscriptionCount.incrementAndGet();
                log.debug("Flux subscribed: {}", name);
            })
            .doOnCancel(() -> {
                subscriptionCount.decrementAndGet();
                log.debug("Flux cancelled: {}", name);
            })
            .doOnTerminate(() -> {
                subscriptionCount.decrementAndGet();
                log.debug("Flux terminated: {}", name);
            })
            .doOnRequest(n -> log.trace("Flux {} requested {} elements", name, n))
            .doOnNext(item -> log.trace("Flux {} emitted item", name))
            .onBackpressureBuffer(100, 
                buffer -> {
                    backpressureEvents.increment();
                    log.warn("Backpressure buffer overflow in {}", name);
                },
                BufferOverflowStrategy.DROP_OLDEST);
    }
    
    /**
     * 监控Mono性能
     */
    public <T> Mono<T> monitorMono(String name, Mono<T> mono) {
        return mono
            .doOnSubscribe(s -> {
                subscriptionCount.incrementAndGet();
                log.debug("Mono subscribed: {}", name);
            })
            .doOnSuccess(item -> {
                subscriptionCount.decrementAndGet();
                log.debug("Mono completed successfully: {}", name);
            })
            .doOnError(error -> {
                subscriptionCount.decrementAndGet();
                log.error("Mono failed: {}", name, error);
            })
            .doOnCancel(() -> {
                subscriptionCount.decrementAndGet();
                log.debug("Mono cancelled: {}", name);
            });
    }
    
    /**
     * 记录请求处理时间
     */
    public Mono<ServerResponse> timeRequest(ServerRequest request, 
                                           Mono<ServerResponse> responseMono) {
        long startTime = System.nanoTime();
        
        return responseMono
            .doOnSuccess(response -> {
                long duration = System.nanoTime() - startTime;
                webfluxRequestTimer.record(duration, TimeUnit.NANOSECONDS);
                
                log.debug("Request {} {} processed in {} ns", 
                    request.method(), request.path(), duration);
            });
    }
    
    /**
     * 线程池监控
     */
    @EventListener
    public void monitorThreadPools(ApplicationReadyEvent event) {
        Schedulers.enableMetrics();
        
        // 监控并行调度器
        Gauge.builder("schedulers.parallel.active")
            .description("Parallel scheduler active threads")
            .register(meterRegistry, Schedulers.parallel(), 
                s -> ((SchedulerMetrics) s).activeTasks());
            
        // 监控弹性调度器
        Gauge.builder("schedulers.elastic.active")
            .description("Elastic scheduler active threads")
            .register(meterRegistry, Schedulers.boundedElastic(),
                s -> ((SchedulerMetrics) s).activeTasks());
    }
}

// 响应式缓存配置
@Configuration
@Slf4j
public class ReactiveCacheConfiguration {
    
    @Bean
    public ReactiveCacheManager reactiveCacheManager() {
        return new ReactiveRedisCacheManager(
            ReactiveRedisConnectionFactory connectionFactory,
            RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofMinutes(10))
                .serializeValuesWith(RedisSerializationContext.SerializationPair
                    .fromSerializer(new Jackson2JsonRedisSerializer<>(Object.class)))
        );
    }
    
    @Bean
    public CacheAspectSupport cacheAspect() {
        return new ReactiveCachingAspect(reactiveCacheManager());
    }
}

// 响应式健康检查
@Component
@Slf4j
public class ReactiveHealthIndicator implements ReactiveHealthIndicator {
    
    private final ReactiveUserRepository userRepository;
    private final Sinks.Many<HealthEvent> healthEventSink;
    
    public ReactiveHealthIndicator(ReactiveUserRepository userRepository) {
        this.userRepository = userRepository;
        this.healthEventSink = Sinks.many().multicast().onBackpressureBuffer();
    }
    
    @Override
    public Mono<Health> health() {
        return checkDatabaseConnection()
            .timeout(Duration.ofSeconds(5))
            .map(connected -> {
                if (connected) {
                    Health health = Health.up()
                        .withDetail("database", "connected")
                        .withDetail("timestamp", Instant.now())
                        .build();
                    
                    healthEventSink.tryEmitNext(new HealthEvent("HEALTH_CHECK", health));
                    return health;
                } else {
                    Health health = Health.down()
                        .withDetail("database", "disconnected")
                        .withDetail("timestamp", Instant.now())
                        .build();
                    
                    healthEventSink.tryEmitNext(new HealthEvent("HEALTH_CHECK_FAILED", health));
                    return health;
                }
            })
            .onErrorResume(error -> {
                log.error("Health check failed", error);
                Health health = Health.down(error).build();
                healthEventSink.tryEmitNext(new HealthEvent("HEALTH_CHECK_ERROR", health));
                return Mono.just(health);
            });
    }
    
    private Mono<Boolean> checkDatabaseConnection() {
        return userRepository.count()
            .map(count -> true)
            .onErrorReturn(false);
    }
    
    public Flux<HealthEvent> healthEvents() {
        return healthEventSink.asFlux();
    }
}

@Data
@AllArgsConstructor
class HealthEvent {
    private String type;
    private Health health;
    private Instant timestamp = Instant.now();
}

总结

🎯 响应式编程核心价值

  1. 性能优势

    • 非阻塞I/O提升并发处理能力
    • 背压机制防止系统过载
    • 资源高效利用
  2. 编程模型

    • 声明式编程提升代码可读性
    • 函数式编程增强代码可维护性
    • 流式处理简化复杂业务逻辑
  3. 系统架构

    • 更好的弹性设计
    • 改进的可伸缩性
    • 增强的容错能力

🚀 WebFlux实战要点

  1. 控制器设计

    • 合理使用Flux和Mono
    • 正确处理背压
    • 优化数据流处理
  2. 错误处理

    • 全局异常处理机制
    • 重试和回退策略
    • 超时控制
  3. 性能优化

    • 调度器合理配置
    • 缓存策略优化
    • 连接池管理

🔌 RSocket核心特性

  1. 交互模式

    • 请求-响应:传统RPC模式
    • 请求-流:数据流传输
    • 即发-忘:日志、指标上报
    • 通道:双向数据流
  2. 协议优势

    • 二进制协议高性能
    • 应用层流量控制
    • 多语言支持

📋 生产环境建议

  1. 监控告警

    • 响应式流监控
    • 背压事件告警
    • 线程池使用监控
  2. 调试排查

    • 启用详细日志
    • 使用调试操作符
    • 性能 profiling
  3. 容量规划

    • 合理设置缓冲区
    • 线程池大小调优
    • 内存使用评估

响应式编程代表了现代应用开发的未来方向,掌握WebFlux和RSocket将帮助您构建更高性能、更弹性的分布式系统。


下一篇预告:《MySQL高级优化与架构设计:从索引优化到分库分表》

如果觉得本文对你有帮助,请点赞、收藏、关注!欢迎在评论区分享你的响应式编程实践经验和问题。

相关推荐
异步的告白2 小时前
C语言-数据结构-2-单链表程序-增删改查
c语言·开发语言·数据结构
.豆鲨包2 小时前
【Android】深入理解Activity的生命周期和IntentFilter
android·java
CryptoRzz2 小时前
印度股票数据 PHP 对接文档 覆盖 BSE(孟买证券交易所)和 NSE(印度国家证券交易所)的实时数据
android·服务器·开发语言·区块链·php
lkbhua莱克瓦242 小时前
集合进阶6——TreeMap底层原理
java·开发语言·笔记·学习方法·hashmap
普通网友2 小时前
内存对齐与缓存友好设计
开发语言·c++·算法
JEECG低代码平台2 小时前
GitHub 十大 Java 语言 AI 开源项目推荐
java·人工智能·github
小咖张2 小时前
idea 启动失败,不加载自己的配置文件
java·ide·intellij-idea
lsx2024062 小时前
DOM 节点信息
开发语言
m***11902 小时前
使用IDEA环境编译Spring源码及spring源码调试环境搭建
java·spring·intellij-idea