Skip to main content

Spring 微服务开发库选型收集

[服务发现] Eureka Server

Maven: org.springframework.cloud:spring-cloud-starter-netflix-eureka-server

流行服务发现工具,支持健康检查和 UI 界面。

  • 配置
# application.yml
eureka:
  client:
    # 关闭自注册,避免 Eureka server 把自己也注册进去
    registerWithEureka: false
    fetchRegistry: false
server:
   port: 8761
  • 入口声明
@EnableEurekaServer // 启用 eureka server
@SpringBootApplication
public class MyApplication { ... }
  • 访问界面

启动服务后,可访问 localhost:8761/ UI 界面。

[服务发现客户端] Eureka Client

声明+配置,将业务服务注册到 Eureka server。

  • 配置
# application.yml
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka # server 位置,多个 eureka server 可用逗号隔开
spring:
  application:
    name: store # 注册的服务名
  • 入口声明
@EnableEurekaClient // 启用 eureka client
@SpringBootApplication
public class MyApplication { ... }

之后 Eureka Client 将读取配置,注册服务,然后定时发送心跳。

服务端可以用 UI 查看已注册的服务。

[请求工具] RestTemplate

Maven: org.springframework:spring-web

封装了 HTTP 构建、编码、解码的过程。只传入 URL 即可发起请求。

  • 初始化
@Bean
public RestTemplate restTemplate() {
  return new RestTemplate();
}
  • 自动装配
@Autowired
private RestTemplate restTemplate;
  • 发起请求
void do () {
  // 发起 Get 请求,并将 body 解码到 Book 对象
  ResponseEntity<Book> responseEntity = restTemplate.getForEntity("http://example", Book.class);

  // 发起 Get 请求,并将 body 解码到 Book 对象,进一步封装
  Book book = restTemplate.getForObject("http://example", Book.class);

  // 发起 Post 请求,并将 body 解码到 Book 对象
  ResponseEntity<Book> book = restTemplate.postForEntity("http://example", new PostBook(), Book.class);

  // URI 模板,传可变参数
  restTemplate.getForEntity("http://example?name={1}&tag={2}", Book.class, "book name", "book tag");

  // URI 模板,传 Map 参数
  restTemplate.getForEntity("http://example?name={name}", Book.class, new HashMap(){{ put("name", "book name") }});
}

[服务发现客户端] Ribbon

服务间的负载均衡客户端,支持 eureka 和 静态服务配置。

Maven: org.springframework.cloud:spring-cloud-starter-netflix-ribbon

  • 初始化

application.yml 配置 eureka 后,Ribbon 可以自动识别到注册中心。

或者直接写死目标服务:

# application.yml
# 定义服务 stores,含 2 个节点
stores:
  ribbon:
    listOfServers: example.com,google.com
  • 手动选择服务
// 自动装配
@Autowired
private LoadBalancerClient loadBalancer;

void do () {
  // 选择一个名为 stores 的服务
  ServiceInstance instance = loadBalancer.choose("stores");
  // 从中获取 ip 和 port,并构建成 URI
  URI storesUri = URI.create(String.format("http://%s:%s", instance.getHost(), instance.getPort()));
  // 可以用 URI 发起 HTTP 请求...
}
  • 应用到 Rest Template 实现服务负载均衡请求

    1. 带负载均衡初始化 Rest Template
    @Bean
    @LoadBalanced //添加该注解,可以直接通过服务名找到对应的IP地址
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
    
    1. 发起请求
    // 向服务 stores 发起请求,Ribbon 自动转换成实际节点
    ResponseEntity<Book> responseEntity = restTemplate.getForEntity("http://stores", Book.class);
    

[请求工具] OpenFeign

声明式请求工具,不用自己创建 Bean,直接装配接口即可。自带 Ribbon 做负载均衡客户端。

Maven: org.springframework.cloud:spring-cloud-starter-openfeign

  • 初始化
@EnableFeignClients // 启用 feign 功能
@SpringBootApplication
public class SpringBootApp { ... }
  • 声明接口
@FeignClient(name = "stores") // 目标服务为 stores
public interface BookStoreClient {

  @GetMapping("/books")
  List<Book> getBooks(@RequestParam("name") String bookName);
  
  // 可以用 @RequestHeader 传入自定义 Header
  @PostMapping("/book")
  Book addBook(@RequestHeader("Authorization") String token, @RequestBody PostBook book);
}
  • 自动装配
@Autowired
private BookStoreClient client;
  • 发起请求
void do () {
  List<Book> books = client.getBooks("book name");

  Book responseBook = client.addBook("JWT Authoriz", new PostBook());
}

引用

[极乐科技-极乐君] RestTemplate 详解

Client Side Load Balancer: Ribbon

使用RestTemplate和Feign进行微服务通信

Service Registration with Eureka