java流式编程学习

// 自定义状态策略

package com.example.streamingorchestration.strategy;

import com.alibaba.graphscope.groot.runtime.KeyStrategy;

import java.util.ArrayList;

import java.util.List;

/**

* 追加策略 - 用于列表类型数据的累积

*/

public class AppendStrategy implements KeyStrategy {

@Override

public Object apply(Object currentValue, Object newValue) {

if (currentValue == null) {

if (newValue instanceof List) {

return new ArrayList<>((List<?>) newValue);

} else {

List<Object> list = new ArrayList<>();

list.add(newValue);

return list;

}

}

if (currentValue instanceof List && newValue instanceof List) {

List<Object> currentList = (List<Object>) currentValue;

List<Object> newList = (List<Object>) newValue;

currentList.addAll(newList);

return currentList;

} else if (currentValue instanceof List) {

List<Object> currentList = (List<Object>) currentValue;

currentList.add(newValue);

return currentList;

} else {

List<Object> newList = new ArrayList<>();

newList.add(currentValue);

newList.add(newValue);

return newList;

}

}

}

/**

* 递增策略 - 用于计数器

*/

public class IncrementStrategy implements KeyStrategy {

@Override

public Object apply(Object currentValue, Object newValue) {

Integer current = currentValue != null ? (Integer) currentValue : 0;

Integer increment = newValue != null ? (Integer) newValue : 1;

return current + increment;

}

}

/**

* 最大值策略 - 保留最大值

*/

public class MaxValueStrategy implements KeyStrategy {

@Override

public Object apply(Object currentValue, Object newValue) {

if (currentValue == null) return newValue;

if (newValue == null) return currentValue;

if (currentValue instanceof Comparable && newValue instanceof Comparable) {

return ((Comparable) currentValue).compareTo(newValue) >= 0 ? currentValue : newValue;

}

return newValue; // 无法比较时使用新值

}

}

// StreamWeatherService.java

@Service

public class StreamWeatherService {

private final Random random = new Random();

// 服务A - 快速但精度一般

public Flux<String> getWeatherStreamA(String city) {

return Flux.range(0, 5)

.delayElements(Duration.ofMillis(100))

.map(i -> {

double temp = 20.0 + (city.hashCode() % 15) + random.nextDouble() * 4 - 2;

String condition = getRandomConditionA();

return String.format("ServiceA|%s|%.1f|%s|%d", city, temp, condition, i);

});

}

// 服务B - 中等速度,较好精度

public Flux<String> getWeatherStreamB(String city) {

return Flux.range(0, 8)

.delayElements(Duration.ofMillis(150))

.map(i -> {

double temp = 20.5 + (city.hashCode() % 14) + random.nextDouble() * 3 - 1.5;

String condition = getRandomConditionB();

return String.format("ServiceB|%s|%.1f|%s|%d", city, temp, condition, i);

});

}

// 服务C - 较慢但高精度

public Flux<String> getWeatherStreamC(String city) {

return Flux.range(0, 10)

.delayElements(Duration.ofMillis(200))

.map(i -> {

double temp = 19.8 + (city.hashCode() % 16) + random.nextDouble() * 2 - 1;

String condition = getRandomConditionC();

return String.format("ServiceC|%s|%.1f|%s|%d", city, temp, condition, i);

});

}

private String getRandomConditionA() {

String[] conditions = {"Sunny", "Partly Cloudy", "Cloudy", "Light Rain"};

return conditions[random.nextInt(conditions.length)];

}

private String getRandomConditionB() {

String[] conditions = {"Clear", "Mostly Sunny", "Overcast", "Drizzle"};

return conditions[random.nextInt(conditions.length)];

}

private String getRandomConditionC() {

String[] conditions = {"Fair", "Scattered Clouds", "Broken Clouds", "Light Showers"};

return conditions[random.nextInt(conditions.length)];

}

// 解析流数据并计算评分

public Double calculateScoreFromStream(List<String> streamData) {

if (streamData == null || streamData.isEmpty()) {

return 0.0;

}

// 基于数据完整性、响应速度和数据一致性评分

double completenessScore = Math.min(1.0, streamData.size() / 8.0);

double consistencyScore = calculateConsistency(streamData);

return (completenessScore * 0.6 + consistencyScore * 0.4) * 10;

}

private double calculateConsistency(List<String> streamData) {

// 简化的数据一致性检查

try {

Set<String> uniqueTemps = streamData.stream()

.map(data -> data.split("\\|")[2]) // 温度字段

.collect(Collectors.toSet());

return Math.min(1.0, 1.0 / (uniqueTemps.size() * 0.5));

} catch (Exception e) {

return 0.5;

}

}

}

// WeatherSelectorEdgeAction.java

@Component

public class WeatherSelectorEdgeAction implements EdgeAction {

@Override

public String apply(OverAllState state) throws Exception {

String currentService = (String) state.value("current_service");

Double currentScore = (Double) state.value("current_score");

System.out.println("🔍 选择器检查: 服务 " + currentService + " 评分=" + currentScore);

// 策略1: 如果评分>=8.0,提前返回最佳结果

if (currentScore != null && currentScore >= 8.0) {

System.out.println("✅ 服务 " + currentService + " 评分达标,提前返回最佳结果");

return "best_result_selector";

}

// 策略2: 根据当前服务决定下一步

switch (currentService) {

case "A":

return "service_b"; // 继续服务B

case "B":

Double scoreA = (Double) state.value("service_a_score");

Double scoreB = (Double) state.value("service_b_score");

// 如果服务B明显优于服务A,可以提前选择

if (scoreB != null && scoreA != null && scoreB - scoreA > 2.0) {

return "best_result_selector";

}

return "service_c"; // 继续服务C

case "C":

return "best_result_selector"; // 所有服务完成,选择最佳结果

default:

return "best_result_selector";

}

}

}

// ParallelWeatherSelector.java

@Component

public class ParallelWeatherSelector implements NodeAction {

@Override

public OverAllState execute(OverAllState state) throws Exception {

System.out.println("🔄 并行选择器开始选择最佳结果...");

// 收集所有服务的评分

Map<String, Double> serviceScores = new HashMap<>();

String[] services = {"A", "B", "C"};

for (String service : services) {

Double score = (Double) state.value("service_" + service + "_score");

if (score != null) {

serviceScores.put(service, score);

System.out.println("📊 服务 " + service + " 最终评分: " + score);

}

}

// 选择评分最高的服务

Map.Entry<String, Double> bestEntry = serviceScores.entrySet().stream()

.max(Map.Entry.comparingByValue())

.orElse(null);

if (bestEntry != null) {

String bestService = bestEntry.getKey();

Double bestScore = bestEntry.getValue();

state.put("best_service", bestService);

state.put("best_score", bestScore);

// 获取最佳服务的流数据

Flux<String> bestStream = (Flux<String>) state.value("service_" + bestService + "_stream");

state.put("best_stream", bestStream);

System.out.println("🏆 选择最佳服务: " + bestService + " (评分: " + bestScore + ")");

}

return state;

}

}

// StreamWeatherNode.java

@Component

public class StreamWeatherNode implements NodeAction {

@Autowired

private StreamWeatherService weatherService;

@Override

public OverAllState execute(OverAllState state) throws Exception {

String city = (String) state.value("city");

String serviceType = (String) state.value("service_type");

System.out.println("🌤️ 开始调用天气服务 " + serviceType + " 查询城市: " + city);

// 调用对应的流式天气服务

Flux<String> weatherStream;

switch (serviceType) {

case "A":

weatherStream = weatherService.getWeatherStreamA(city);

break;

case "B":

weatherStream = weatherService.getWeatherStreamB(city);

break;

case "C":

weatherStream = weatherService.getWeatherStreamC(city);

break;

default:

throw new IllegalArgumentException("未知的服务类型: " + serviceType);

}

// 缓存流数据用于评分

Mono<List<String>> collectedStream = weatherStream.collectList();

List<String> streamData = collectedStream.block(); // 在实际生产环境中应使用异步方式

// 计算评分

Double score = weatherService.calculateScoreFromStream(streamData);

// 重新创建流(因为原来的流已经被消费)

Flux<String> newStream = Flux.fromIterable(streamData);

// 保存结果到状态

state.put("service_" + serviceType + "_stream", newStream);

state.put("service_" + serviceType + "_score", score);

state.put("service_" + serviceType + "_data", streamData);

state.put("current_service", serviceType);

state.put("current_score", score);

System.out.println("✅ 服务 " + serviceType + " 完成,评分: " + score);

return state;

}

}

// StartNode.java

@Component

public class StartNode implements NodeAction {

@Override

public OverAllState execute(OverAllState state) throws Exception {

System.out.println("🚀 开始天气查询工作流");

String city = (String) state.value("city");

System.out.println("📍 查询城市: " + city);

state.put("start_time", System.currentTimeMillis());

return state;

}

}

// FinalResultNode.java

@Component

public class FinalResultNode implements NodeAction {

@Override

public OverAllState execute(OverAllState state) throws Exception {

Long startTime = (Long) state.value("start_time");

Long endTime = System.currentTimeMillis();

state.put("total_execution_time", endTime - startTime);

String bestService = (String) state.value("best_service");

Double bestScore = (Double) state.value("best_score");

System.out.println("🎉 工作流执行完成!");

System.out.println("🏆 最佳服务: " + bestService + ", 评分: " + bestScore);

System.out.println("⏱️ 总执行时间: " + (endTime - startTime) + "ms");

return state;

}

}

// WeatherGraphConfig.java

@Configuration

public class WeatherGraphConfig {

@Bean

public StateGraph sequentialWeatherGraph() throws GraphStateException {

OverAllStateFactory factory = () -> {

OverAllState state = new OverAllState();

// 注册状态键和更新策略

state.registerKeyAndStrategy("city", new ReplaceStrategy());

state.registerKeyAndStrategy("service_type", new ReplaceStrategy());

state.registerKeyAndStrategy("current_service", new ReplaceStrategy());

state.registerKeyAndStrategy("current_score", new ReplaceStrategy());

state.registerKeyAndStrategy("start_time", new ReplaceStrategy());

state.registerKeyAndStrategy("service_A_stream", new ReplaceStrategy());

state.registerKeyAndStrategy("service_B_stream", new ReplaceStrategy());

state.registerKeyAndStrategy("service_C_stream", new ReplaceStrategy());

state.registerKeyAndStrategy("service_A_score", new ReplaceStrategy());

state.registerKeyAndStrategy("service_B_score", new ReplaceStrategy());

state.registerKeyAndStrategy("service_C_score", new ReplaceStrategy());

state.registerKeyAndStrategy("best_service", new ReplaceStrategy());

state.registerKeyAndStrategy("best_score", new ReplaceStrategy());

state.registerKeyAndStrategy("best_stream", new ReplaceStrategy());

state.registerKeyAndStrategy("total_execution_time", new ReplaceStrategy());

return state;

};

StateGraph stateGraph = new StateGraph("串行天气查询工作流", factory)

.addNode("start", AsyncNodeAction.node_async(new StartNode()))

.addNode("service_a", AsyncNodeAction.node_async(new StreamWeatherNode()))

.addNode("service_b", AsyncNodeAction.node_async(new StreamWeatherNode()))

.addNode("service_c", AsyncNodeAction.node_async(new StreamWeatherNode()))

.addNode("best_result_selector", AsyncNodeAction.node_async(new ParallelWeatherSelector()))

.addNode("final_result", AsyncNodeAction.node_async(new FinalResultNode()))

// 串行执行流程

.addEdge(StateGraph.START, "start")

.addEdge("start", "service_a")

// 条件边:根据选择器决定下一步

.addConditionalEdges("service_a",

AsyncEdgeAction.edge_async(new WeatherSelectorEdgeAction()),

Map.of("service_b", "service_b", "best_result_selector", "best_result_selector"))

.addConditionalEdges("service_b",

AsyncEdgeAction.edge_async(new WeatherSelectorEdgeAction()),

Map.of("service_c", "service_c", "best_result_selector", "best_result_selector"))

.addEdge("service_c", "best_result_selector")

.addEdge("best_result_selector", "final_result")

.addEdge("final_result", StateGraph.END);

return stateGraph;

}

@Bean

public StateGraph parallelWeatherGraph() throws GraphStateException {

OverAllStateFactory factory = () -> {

OverAllState state = new OverAllState();

// 注册状态键和更新策略(同串行配置)

state.registerKeyAndStrategy("city", new ReplaceStrategy());

state.registerKeyAndStrategy("service_type", new ReplaceStrategy());

state.registerKeyAndStrategy("start_time", new ReplaceStrategy());

state.registerKeyAndStrategy("service_A_stream", new ReplaceStrategy());

state.registerKeyAndStrategy("service_B_stream", new ReplaceStrategy());

state.registerKeyAndStrategy("service_C_stream", new ReplaceStrategy());

state.registerKeyAndStrategy("service_A_score", new ReplaceStrategy());

state.registerKeyAndStrategy("service_B_score", new ReplaceStrategy());

state.registerKeyAndStrategy("service_C_score", new ReplaceStrategy());

state.registerKeyAndStrategy("best_service", new ReplaceStrategy());

state.registerKeyAndStrategy("best_score", new ReplaceStrategy());

state.registerKeyAndStrategy("best_stream", new ReplaceStrategy());

state.registerKeyAndStrategy("total_execution_time", new ReplaceStrategy());

return state;

};

StateGraph stateGraph = new StateGraph("并行天气查询工作流", factory)

.addNode("start", AsyncNodeAction.node_async(new StartNode()))

.addNode("service_a_parallel", AsyncNodeAction.node_async(new StreamWeatherNode()))

.addNode("service_b_parallel", AsyncNodeAction.node_async(new StreamWeatherNode()))

.addNode("service_c_parallel", AsyncNodeAction.node_async(new StreamWeatherNode()))

.addNode("best_result_selector_parallel", AsyncNodeAction.node_async(new ParallelWeatherSelector()))

.addNode("final_result_parallel", AsyncNodeAction.node_async(new FinalResultNode()))

// 并行执行流程

.addEdge(StateGraph.START, "start")

.addEdge("start", "service_a_parallel")

.addEdge("start", "service_b_parallel")

.addEdge("start", "service_c_parallel")

// 所有服务并行执行后汇聚到选择器

.addEdge("service_a_parallel", "best_result_selector_parallel")

.addEdge("service_b_parallel", "best_result_selector_parallel")

.addEdge("service_c_parallel", "best_result_selector_parallel")

.addEdge("best_result_selector_parallel", "final_result_parallel")

.addEdge("final_result_parallel", StateGraph.END);

return stateGraph;

}

}

// WeatherController.java

@RestController

@RequestMapping("/api/weather")

public class WeatherController {

private final CompiledGraph sequentialGraph;

private final CompiledGraph parallelGraph;

@Autowired

public WeatherController(

@Qualifier("sequentialWeatherGraph") StateGraph sequentialGraph,

@Qualifier("parallelWeatherGraph") StateGraph parallelGraph) throws Exception {

this.sequentialGraph = sequentialGraph.compile();

this.parallelGraph = parallelGraph.compile();

}

@PostMapping(value = "/sequential/{city}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)

public Flux<String> getWeatherSequential(@PathVariable String city) throws Exception {

System.out.println("\n=== 开始串行执行模式 ===");

OverAllState initialState = new OverAllState();

initialState.put("city", city);

initialState.put("service_type", "A");

CompiledGraphResponse response = sequentialGraph.call(initialState);

Flux<String> bestStream = (Flux<String>) response.state().value("best_stream");

if (bestStream != null) {

return bestStream.map(data -> "DATA: " + data)

.concatWith(Flux.just("=== 串行执行完成 ==="));

}

return Flux.just("错误: 未能获取天气数据");

}

@PostMapping(value = "/parallel/{city}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)

public Flux<String> getWeatherParallel(@PathVariable String city) throws Exception {

System.out.println("\n=== 开始并行执行模式 ===");

OverAllState initialState = new OverAllState();

initialState.put("city", city);

// 为并行执行准备多个状态

initialState.put("service_type", "A");

CompiledGraphResponse response = parallelGraph.call(initialState);

Flux<String> bestStream = (Flux<String>) response.state().value("best_stream");

if (bestStream != null) {

return bestStream.map(data -> "DATA: " + data)

.concatWith(Flux.just("=== 并行执行完成 ==="));

}

return Flux.just("错误: 未能获取天气数据");

}

}

// MainApplication.java

@SpringBootApplication

public class WeatherOrchestrationApplication {

public static void main(String[] args) {

SpringApplication.run(WeatherOrchestrationApplication.class, args);

}

}

相关推荐
ʚ希希ɞ ྀ3 小时前
SpringBoot的学习
java·spring boot·学习
notillusion3 小时前
TRX#22597
java·php·程序优化
冬天的雪20084 小时前
java内存性能优化工具Mat
java·开发语言
Le1Yu4 小时前
消息队列以及RabbitMQ的使用
java·开发语言
羚羊角uou4 小时前
【Linux】线程池
java·开发语言
阿拉-M834 小时前
IntelliJ IDEA Windows 系统高频快捷键使用手册
java·windows·intellij-idea
lingggggaaaa5 小时前
小迪安全v2023学习笔记(一百三十四讲)—— Windows权限提升篇&数据库篇&MySQL&MSSQL&Oracle&自动化项目
java·数据库·windows·笔记·学习·安全·网络安全