Skip to content

Spring Cloud Hoxton 版本

官方介绍

Spring Cloud Hoxton 是 Spring Cloud 的重要版本,于 2019 年底发布。该版本基于 Spring Boot 2.2.x 构建,进一步完善了微服务架构的各项功能,包括服务治理、配置管理、API 网关、安全认证等核心组件。

Hoxton 版本标志着 Spring Cloud 项目向更加模块化和现代化的方向发展,引入了更多响应式编程特性和云原生支持。

版本特性

1. Spring Cloud Commons 增强

  • 支持 reactive DiscoveryClient 实现
  • 更好的负载均衡器抽象
  • 改进的服务注册与发现机制

2. Spring Cloud Gateway 响应式增强

  • 更多的路由谓词工厂
  • 增强的过滤器功能
  • 改进的性能和稳定性

3. Spring Cloud LoadBalancer

  • 全新的客户端负载均衡器实现
  • 支持反应式编程模型
  • 更好的可扩展性

4. Spring Cloud OpenFeign 增强

  • 支持 WebClient 替代 RestTemplate
  • 更好的响应式支持
  • 改进的编码和解码机制

5. Spring Cloud Security 更新

  • OAuth2 客户端支持改进
  • 更好的 JWT 集成
  • 增强的授权服务器支持

官方获取地址

Maven 依赖

xml
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Hoxton.SR12</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

Gradle 依赖

gradle
dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:Hoxton.SR12"
    }
}

官方文档

环境要求

  • Java 8 或更高版本 (Java 11+ 推荐)
  • Spring Boot 2.2.x 或 2.3.x
  • Maven 3.5+ 或 Gradle 5.6+
  • 推荐使用 Spring Boot 2.3.12.RELEASE 以获得最佳兼容性

部署方法

1. 创建 Spring Cloud 项目

bash
# 使用 Spring Initializr 创建项目
curl https://start.spring.io/starter.tgz \
  -d groupId=com.example \
  -d artifactId=spring-cloud-hoxton-service \
  -d name=hoxton-service \
  -d packaging=jar \
  -d bootVersion=2.3.12.RELEASE \
  -d javaVersion=8 \
  -d language=java \
  -d type=maven-project \
  -d baseDir=hoxton-service \
  -d packageName=com.example \
  -d dependencies=cloud-eureka,cloud-config-client,cloud-gateway,cloud-openfeign \
  | tar -xzvf -

2. 配置服务注册中心

java
package com.example.hoxton.eureka;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}

application.yml:

yaml
server:
  port: 8761

eureka:
  instance:
    hostname: localhost
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
  server:
    enable-self-preservation: false
    renewal-percent-threshold: 0.49

3. 配置服务消费者

java
package com.example.hoxton.consumer;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

@SpringBootApplication
@EnableFeignClients
@RestController
public class ConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }

    @Autowired
    private UserService userService;

    @GetMapping("/user/{id}")
    public Mono<String> getUser(@PathVariable Long id) {
        return userService.getUser(id);
    }

    @FeignClient(name = "user-service", path = "/api")
    public interface UserService {
        @GetMapping("/users/{id}")
        Mono<String> getUser(@PathVariable Long id);
    }

    @Bean
    public WebClient.Builder webClientBuilder() {
        return WebClient.builder();
    }
}

4. 部署到容器

Dockerfile:

dockerfile
FROM openjdk:11-jre-slim
VOLUME /tmp
COPY target/hoxton-service.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
bash
# 构建 Docker 镜像
docker build -t spring-cloud-hoxton:latest .

# 运行服务
docker run -d -p 8080:8080 spring-cloud-hoxton:latest

二次开发

1. 自定义负载均衡器

java
package com.example.hoxton.lb;

import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient;
import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;

@Configuration
@LoadBalancerClient(value = "user-service", configuration = CustomLoadBalancerConfig.class)
public class LoadBalancerConfiguration {

    @Bean
    public ReactorLoadBalancer<ServiceInstance> customLoadBalancer(Environment environment,
                                                                   LoadBalancerClientFactory loadBalancerClientFactory) {
        String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
        return new CustomRoundRobinLoadBalancer(
                loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class),
                name);
    }
}

2. 自定义断路器

java
package com.example.hoxton.circuitbreaker;

import io.github.resilience4j.circuitbreaker.CircuitBreaker;
import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig;
import org.springframework.cloud.circuitbreaker.resilience4j.Resilience4JCircuitBreakerFactory;
import org.springframework.cloud.circuitbreaker.resilience4j.Resilience4JConfigBuilder;
import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.time.Duration;

@Configuration
public class CircuitBreakerConfiguration {

    @Bean
    public CircuitBreakerFactory circuitBreakerFactory() {
        Resilience4JCircuitBreakerFactory factory = new Resilience4JCircuitBreakerFactory();
        factory.configureDefault(id -> new Resilience4JConfigBuilder(id)
                .circuitBreakerConfig(CircuitBreakerConfig.custom()
                        .slidingWindowSize(10)
                        .failureRateThreshold(50)
                        .waitDurationInOpenState(Duration.ofMillis(1000))
                        .permittedNumberOfCallsInHalfOpenState(3)
                        .build())
                .build());
        return factory;
    }
}

配置示例

1. 服务消费者配置

application.yml:

yaml
server:
  port: 8080

spring:
  application:
    name: hoxton-consumer
  cloud:
    loadbalancer:
      ribbon:
        enabled: false
      configuration:
        - LoadBalancerConfiguration

feign:
  client:
    config:
      default:
        connectTimeout: 5000
        readTimeout: 5000
  httpclient:
    enabled: false
  okhttp:
    enabled: true
  compression:
    request:
      enabled: true
    response:
      enabled: true

resilience4j:
  circuitbreaker:
    instances:
      backendA:
        sliding-window-size: 10
        failure-rate-threshold: 50
        wait-duration-in-open-state: 1000ms
  retry:
    instances:
      backendA:
        max-attempts: 3
        wait-duration: 1000ms

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true

logging:
  level:
    org.springframework.cloud: DEBUG
    org.springframework.web: DEBUG

2. 服务提供者配置

application.yml:

yaml
server:
  port: 8081

spring:
  application:
    name: user-service

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  instance:
    lease-renewal-interval-in-seconds: 10
    lease-expiration-duration-in-seconds: 30

management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,circuitbreakers,refresh
  endpoint:
    health:
      show-details: always

参考资源

版本历史

  • Hoxton.M1 (2019-09-26): 初始里程碑版本
  • Hoxton.RC1 (2019-10-23): 第一个候选发布版本
  • Hoxton.RELEASE (2019-11-27): 正式发布版本
  • Hoxton.SR1-SR12 (2019-12-16 至 2021-06-24): 各个小版本修复更新