第505集Java中台实战
|字数总计:3.4k|阅读时长:15分钟|阅读量:
Java中台实战
1. 概述
1.1 中台架构的重要性
中台架构是一种企业级架构模式,通过将业务能力抽象为可复用的服务,实现业务能力的沉淀和复用,提高开发效率和业务响应速度。
本文内容:
- 中台架构设计:中台架构原理和设计思路
- 服务化拆分:业务服务化拆分策略
- 微服务治理:微服务架构和服务治理
- API网关:统一入口和路由管理
- 服务注册发现:服务注册和发现机制
- 配置中心:统一配置管理
- 实战案例:完整的中台系统建设
1.2 本文内容结构
本文将从以下几个方面深入探讨Java中台实战:
- 中台架构设计:中台架构原理和设计思路
- 服务化拆分:业务服务化拆分策略
- 微服务治理:微服务架构和服务治理
- API网关:统一入口和路由管理
- 服务注册发现:服务注册和发现机制
- 配置中心:统一配置管理
- 分布式事务:分布式事务处理
- 实战案例:完整的中台系统建设
2. 中台架构设计
2.1 中台架构概述
2.1.1 中台架构特点
中台架构:将业务能力抽象为可复用的服务,实现业务能力的沉淀和复用。
中台架构特点:
- 业务复用:业务能力可复用
- 快速响应:快速响应业务需求
- 统一标准:统一的技术标准和规范
- 能力沉淀:业务能力沉淀和积累
- 服务化:业务服务化拆分
- 平台化:技术平台化支撑
中台 vs 前台 vs 后台:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
|
public class MiddlePlatformArchitecture { public class FrontendApp { } public class MiddlePlatformService { } public class BackendSystem { } }
|
2.2 中台架构设计
2.2.1 中台分层架构
中台分层架构:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
public class MiddlePlatformLayers { public class BusinessMiddlePlatform { } public class DataMiddlePlatform { } public class TechnicalMiddlePlatform { } }
|
3. 服务化拆分
3.1 服务拆分策略
3.1.1 领域驱动设计
服务拆分策略:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
|
public class ServiceSplitStrategy { public class UserService { } public class OrderService { } public class ProductService { } public class PaymentService { } }
|
3.2 服务接口设计
3.2.1 RESTful API设计
RESTful API设计:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| import org.springframework.web.bind.annotation.*;
@RestController @RequestMapping("/api/v1/users") public class UserController { @Autowired private UserService userService; @PostMapping public Result<User> createUser(@RequestBody UserDTO userDTO) { User user = userService.createUser(userDTO); return Result.success(user); } @GetMapping("/{userId}") public Result<User> getUser(@PathVariable Long userId) { User user = userService.getUser(userId); return Result.success(user); } @PutMapping("/{userId}") public Result<User> updateUser(@PathVariable Long userId, @RequestBody UserDTO userDTO) { User user = userService.updateUser(userId, userDTO); return Result.success(user); } @DeleteMapping("/{userId}") public Result<Void> deleteUser(@PathVariable Long userId) { userService.deleteUser(userId); return Result.success(); } @GetMapping public Result<PageResult<User>> listUsers( @RequestParam(defaultValue = "1") int page, @RequestParam(defaultValue = "10") int size) { PageResult<User> users = userService.listUsers(page, size); return Result.success(users); } }
|
4. 微服务治理
4.1 服务注册发现
4.1.1 Eureka服务注册
Eureka服务注册:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication @EnableEurekaServer public class EurekaServerApplication { public static void main(String[] args) { SpringApplication.run(EurekaServerApplication.class, args); } }
import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication @EnableEurekaClient public class UserServiceApplication { public static void main(String[] args) { SpringApplication.run(UserServiceApplication.class, args); } }
|
4.1.2 Nacos服务注册
Nacos服务注册:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| import com.alibaba.cloud.nacos.discovery.EnableNacosDiscovery; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication @EnableNacosDiscovery public class UserServiceApplication { public static void main(String[] args) { SpringApplication.run(UserServiceApplication.class, args); } }
import com.alibaba.nacos.api.naming.NamingService; import com.alibaba.nacos.api.naming.pojo.Instance;
@Service public class ServiceDiscovery { @Autowired private NamingService namingService; public List<Instance> getInstances(String serviceName) { try { return namingService.getAllInstances(serviceName); } catch (Exception e) { throw new RuntimeException("Get service instances failed", e); } } public Instance selectHealthyInstance(String serviceName) { List<Instance> instances = getInstances(serviceName); return instances.stream() .filter(Instance::isHealthy) .findFirst() .orElseThrow(() -> new RuntimeException("No healthy instance")); } }
|
4.2 服务调用
4.2.1 Feign服务调用
Feign服务调用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.*;
@FeignClient(name = "user-service", path = "/api/v1/users") public interface UserServiceClient { @GetMapping("/{userId}") Result<User> getUser(@PathVariable("userId") Long userId); @PostMapping Result<User> createUser(@RequestBody UserDTO userDTO); @PutMapping("/{userId}") Result<User> updateUser(@PathVariable("userId") Long userId, @RequestBody UserDTO userDTO); @DeleteMapping("/{userId}") Result<Void> deleteUser(@PathVariable("userId") Long userId); }
@Service public class OrderService { @Autowired private UserServiceClient userServiceClient; public Order createOrder(OrderDTO orderDTO) { Result<User> userResult = userServiceClient.getUser(orderDTO.getUserId()); User user = userResult.getData(); Order order = new Order(); order.setUserId(user.getId()); order.setAmount(orderDTO.getAmount()); return orderRepository.save(order); } }
|
4.2.2 RestTemplate服务调用
RestTemplate服务调用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| import org.springframework.web.client.RestTemplate; import org.springframework.http.*;
@Service public class OrderService { @Autowired private RestTemplate restTemplate; @Autowired private LoadBalancerClient loadBalancerClient; public User getUser(Long userId) { ServiceInstance instance = loadBalancerClient.choose("user-service"); String url = "http://" + instance.getHost() + ":" + instance.getPort() + "/api/v1/users/" + userId; ResponseEntity<Result> response = restTemplate.getForEntity(url, Result.class); Result result = response.getBody(); return (User) result.getData(); } }
|
5. API网关
5.1 Spring Cloud Gateway
5.1.1 网关配置
Spring Cloud Gateway配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| import org.springframework.cloud.gateway.route.RouteLocator; import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;
@Configuration public class GatewayConfig { @Bean public RouteLocator customRouteLocator(RouteLocatorBuilder builder) { return builder.routes() .route("user-service", r -> r .path("/api/v1/users/**") .uri("lb://user-service")) .route("order-service", r -> r .path("/api/v1/orders/**") .uri("lb://order-service")) .route("product-service", r -> r .path("/api/v1/products/**") .uri("lb://product-service")) .route("payment-service", r -> r .path("/api/v1/payments/**") .uri("lb://payment-service")) .build(); } }
|
5.1.2 网关过滤器
网关过滤器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.core.Ordered; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono;
@Component public class AuthFilter implements GlobalFilter, Ordered { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { String token = exchange.getRequest().getHeaders().getFirst("Authorization"); if (token == null || !isValidToken(token)) { exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); return exchange.getResponse().setComplete(); } return chain.filter(exchange); } private boolean isValidToken(String token) { return true; } @Override public int getOrder() { return -100; } }
|
5.2 网关限流
5.2.1 限流配置
网关限流:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import reactor.core.publisher.Mono;
@Configuration public class RateLimitConfig { @Bean public KeyResolver ipKeyResolver() { return exchange -> Mono.just( exchange.getRequest().getRemoteAddress().getAddress().getHostAddress() ); } @Bean public KeyResolver userKeyResolver() { return exchange -> Mono.just( exchange.getRequest().getHeaders().getFirst("userId") ); } @Bean public KeyResolver pathKeyResolver() { return exchange -> Mono.just( exchange.getRequest().getPath().value() ); } }
|
6. 配置中心
6.1 Nacos配置中心
6.1.1 配置管理
Nacos配置管理:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| import com.alibaba.cloud.nacos.NacosConfigProperties; import com.alibaba.nacos.api.config.ConfigService; import com.alibaba.nacos.api.config.listener.Listener; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.stereotype.Component;
@Component @RefreshScope public class ConfigManager { @Autowired private ConfigService configService; @Value("${app.name:default}") private String appName; @Value("${app.version:1.0.0}") private String appVersion; public String getConfig(String dataId, String group) { try { return configService.getConfig(dataId, group, 5000); } catch (Exception e) { throw new RuntimeException("Get config failed", e); } } public void addListener(String dataId, String group, Listener listener) { try { configService.addListener(dataId, group, listener); } catch (Exception e) { throw new RuntimeException("Add listener failed", e); } } }
|
6.2 配置刷新
6.2.1 动态配置刷新
动态配置刷新:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component;
@Component @RefreshScope public class DynamicConfig { @Value("${database.url}") private String databaseUrl; @Value("${database.username}") private String databaseUsername; @Value("${database.password}") private String databasePassword; @Value("${redis.host}") private String redisHost; @Value("${redis.port}") private Integer redisPort; }
|
7. 分布式事务
7.1 Seata分布式事务
7.1.1 Seata配置
Seata分布式事务:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| import io.seata.spring.annotation.datasource.EnableAutoDataSourceProxy; import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication @EnableAutoDataSourceProxy public class OrderServiceApplication { public static void main(String[] args) { SpringApplication.run(OrderServiceApplication.class, args); } }
import io.seata.spring.annotation.GlobalTransactional; import org.springframework.transaction.annotation.Transactional;
@Service public class OrderService { @Autowired private OrderRepository orderRepository; @Autowired private PaymentServiceClient paymentServiceClient; @Autowired private InventoryServiceClient inventoryServiceClient; @GlobalTransactional(rollbackFor = Exception.class) public Order createOrder(OrderDTO orderDTO) { Order order = new Order(); order.setUserId(orderDTO.getUserId()); order.setAmount(orderDTO.getAmount()); order = orderRepository.save(order); inventoryServiceClient.deductInventory( orderDTO.getProductId(), orderDTO.getQuantity() ); paymentServiceClient.createPayment( order.getId(), order.getAmount() ); return order; } }
|
7.2 事务模式
7.2.1 AT模式
AT模式(自动事务):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
@GlobalTransactional public void transfer(Long fromAccountId, Long toAccountId, BigDecimal amount) { accountService.deduct(fromAccountId, amount); accountService.add(toAccountId, amount); }
|
7.2.2 TCC模式
TCC模式(手动事务):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
public interface TccAccountService { @TwoPhaseBusinessAction( name = "deduct", commitMethod = "confirmDeduct", rollbackMethod = "cancelDeduct" ) boolean tryDeduct(@BusinessActionContextParameter("accountId") Long accountId, @BusinessActionContextParameter("amount") BigDecimal amount); boolean confirmDeduct(BusinessActionContext context); boolean cancelDeduct(BusinessActionContext context); }
|
8. 服务监控
8.1 链路追踪
8.1.1 Sleuth链路追踪
Sleuth链路追踪:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import org.springframework.cloud.sleuth.annotation.NewSpan; import org.springframework.cloud.sleuth.annotation.SpanTag; import org.springframework.stereotype.Service;
@Service public class OrderService { @NewSpan("create-order") public Order createOrder(@SpanTag("userId") Long userId, @SpanTag("amount") BigDecimal amount) { return order; } }
|
8.2 服务监控
8.2.1 Micrometer监控
Micrometer监控:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| import io.micrometer.core.instrument.Counter; import io.micrometer.core.instrument.MeterRegistry; import org.springframework.stereotype.Component;
@Component public class OrderMetrics { private final Counter orderCreatedCounter; private final Counter orderFailedCounter; public OrderMetrics(MeterRegistry registry) { this.orderCreatedCounter = Counter.builder("order.created") .description("Number of orders created") .register(registry); this.orderFailedCounter = Counter.builder("order.failed") .description("Number of orders failed") .register(registry); } public void incrementOrderCreated() { orderCreatedCounter.increment(); } public void incrementOrderFailed() { orderFailedCounter.increment(); } }
|
9. 实战案例
9.1 完整中台系统
9.1.1 系统架构
完整中台系统架构:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
|
public class MiddlePlatformSystem { public class APIGateway { } public class BusinessServices { } public class DataServices { } public class InfrastructureServices { } }
|
9.2 服务治理
9.2.1 服务治理配置
服务治理配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate;
@Configuration public class ServiceGovernanceConfig { @Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } @Bean public CircuitBreaker circuitBreaker() { return CircuitBreaker.of("default", CircuitBreakerConfig.custom() .failureRateThreshold(50) .waitDurationInOpenState(Duration.ofSeconds(30)) .slidingWindowSize(10) .build()); } @Bean public RateLimiter rateLimiter() { return RateLimiter.of("default", RateLimiterConfig.custom() .limitRefreshPeriod(Duration.ofSeconds(1)) .limitForPeriod(10) .timeoutDuration(Duration.ofSeconds(1)) .build()); } }
|
10. 总结
10.1 核心要点
- 中台架构:业务能力复用和沉淀
- 服务化拆分:按业务领域拆分服务
- 微服务治理:服务注册发现和调用
- API网关:统一入口和路由管理
- 配置中心:统一配置管理
- 分布式事务:保证数据一致性
- 服务监控:链路追踪和性能监控
10.2 关键理解
- 中台价值:业务能力复用,快速响应业务需求
- 服务拆分:合理的服务拆分策略
- 服务治理:完善的服务治理体系
- 统一标准:统一的技术标准和规范
- 能力沉淀:业务能力沉淀和积累
10.3 最佳实践
- 服务拆分:按业务领域拆分,保持服务独立性
- 接口设计:统一的接口设计规范
- 服务治理:完善的服务注册发现和调用机制
- 配置管理:统一的配置管理和动态刷新
- 监控告警:完善的监控和告警体系
- 容错处理:熔断、降级、限流等容错机制
相关文章: