Spring Cloud快速入门-Eureka

如果商品是一个独立的服务,订单系统也是一个独立的服务,那么它们直接怎么进行交互呢?虽然使用springboot也可以实现两个服务之间的交互但是存在url硬编码问题(ip地址修改需要修改配置文件),并且性能低下。

那应该怎么解决呢? – 通过服务注册、发现的机制来完成。

 

一、微服务注册与发现

Spring Cloud快速入门-Eureka

 

由上图可以看出:

1、服务提供者将服务注册到注册中心

2、服务消费者通过注册中心查找服务

3、查找到服务后进行调用(这里就是无需硬编码url的解决方案)

4、服务的消费者与服务注册中心保持心跳连接,一旦服务提供者的地址发生变更时,注册中心会通知服务消费者。

 

二、注册中心:Eureka

从Eureka 2.0开始Eureka就已经闭源了,不过对国内影响很小,一方面是因为国内很多都使用Eureka 1.X 系列,另一方面是因为Spring Cloud提供了多种注册中心的支持,如:consul、ZooKeeper等,如图所示:

Spring Cloud快速入门-Eureka

 

三、原理

Eureka包含两个组件:Eureka ServerEureka Client。

Eureka Server提供服务注册服务,各个节点启动后,会在Eureka Server中进行注册,这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到。

Eureka Client是一个java客户端,用于简化与Eureka Server的交互,客户端同时也就别一个内置的、使用轮询(round-robin)负载算法的负载均衡器。

在应用启动后,将会向Eureka Server发送心跳,默认周期为30秒,如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,Eureka Server将会从服务注册表中把这个服务节点移除(默认90秒)。

Eureka Server之间通过复制的方式完成数据的同步,Eureka还提供了客户端缓存机制,即使所有的Eureka Server都挂掉,客户端依然可以利用缓存中的信息消费其他服务的API。综上,Eureka通过心跳检查、客户端缓存等机制,确保了系统的高可用性、灵活性和可伸缩性。

1.编写Eureka Server

第一步:创建SpringBoot工程:

Spring Cloud快速入门-Eureka

 

Spring Cloud快速入门-Eureka

Spring Cloud快速入门-Eureka

点击“Next”,之后完成创建。

 

第二步,导入依赖springboot工程创建中已有依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

 

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

 

第三步,编写程序启动类:

@SpringBootApplication
@EnableEurekaServer  //表示是一个Eureka服务注册中心
public class AppEureka {

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

 

第四步,编写application.yml配置文件:

# 服务器端口号配置
server:
  port: 8100
# 服务名称
spring:
  application:
    name: eureka-service
eureka:
  instance:
    #注册中心地址
    hostname: localhost
  #客户端调用地址配置
  client:
    # client访问注册服务中心地址
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka
    #是否从Eureka中获取注册信息,因为自己为注册中心,不会在该应用中的检索服务信息
    fetch-registry: false
    #是否将自己注册到Eureka服务中,因为该应用本身就是注册中心,不需要再注册自己(集群的时候为true
    register-with-eureka: false

 

第五步,启动程序做测试:

Spring Cloud快速入门-Eureka

 

2.将商品微服务注册到Eureka

接下来,我们需要将商品的微服务注册到Eureka服务中。

第一步:修改pom文件,引入Spring Cloud的管理依赖以及eureka服务依赖。

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

 

第二步,修改application.yml配置文件:

#服务端口号(本身是一个web项目)
server:
  port: 8081
#起个名字作为服务名称(该服务注册到eureka注册中心的名称,比如商品服务)
spring:
  application:
    name: app-item
#服务注册到eureka注册中心的地址
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8100/eureka
    #因为该应用为服务提供者,是eureka的一个客户端,需要注册到注册中心
    register-with-eureka: true
    #是否需要从eureka上检索服务
    fetch-registry: true

# 启用ip配置 这样在注册中心列表中看见的是以ip+端口呈现的
instance:
  prefer-ip-address: true

 

第三步,修改启动类,增加@EnableEurekaClient 注解:

@SpringBootApplication
// 声明为Eureka的客户端
@EnableEurekaClient
public class ItemApp{

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

}

 

第四步,启动测试

Spring Cloud快速入门-Eureka

 

3.订单系统从Eureka中发现商品服务

第一步,在订单系统中添加依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

 

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

第二步,修改application.yml配置文件:

#服务端口
server:
  port: 8082
#起个名字作为服务名称(该服务注册到eureka注册中心的名称,比如订单服务)
spring:
    application:
        name: app-order
#服务注册到eureka注册中心的地址
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8100/eureka
    #因为该应用为服务提供者,是eureka的一个客户端,需要注册到注册中心
    register-with-eureka: true
    #是否需要从eureka上检索服务
    fetch-registry: true

# 启用ip配置 这样在注册中心列表中看见的是以ip+端口呈现的
instance:
  prefer-ip-address: true

 

 

步,在启动类中添加@EnableEurekaClient注解 ,获取RestTemplate的方法上加 @LoadBalanced注解

@SpringBootApplication
@EnableEurekaClient
public class OrderApp {
    public static void main(String[] args) {
        SpringApplication.run(OrderApp.class, args);
    }
    /**
     * Spring容器中定义RestTemplate对象
     * @return
     */
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

 

步,修改ItemService的实现逻辑:

@Service
public class ItemService {
    // Spring框架对RESTful方式的http请求做了封装,来简化操作
    @Autowired
    private RestTemplate restTemplate;
    public Item queryItemById(Long id) {
        // 该方法走eureka注册中心调用(去注册中心根据app-item查找服务,这种方式必须先开启负载均衡@LoadBalanced)
        String itemUrl = "http://app-item/item/{id}";
        Item result = restTemplate.getForObject(itemUrl, Item.class, id);
        System.out.println("订单系统调用商品服务,result:" + result);
        return result;
    }
}

 

第五步,启动测试(此时有3个应用:Eureka注册中心、Item服务、order服务)

Spring Cloud快速入门-Eureka

 

在注册中心http://localhost:8100看到有2个客户端:

Spring Cloud快速入门-Eureka

4.订单系统从Eureka中发现商品服务2(Fegin的使用)

Feign是一种负载均衡的HTTP客户端, 使用Feign调用API就像调用本地方法一样,从而避免了调用目标微服务时,需要不断的解析/封装json数据的繁琐。

Fegin是一个声明似的web服务客户端,它使得编写web服务客户端变得更加容易。使用Fegin创建一个接口并对它进行注解。它具有可插拔的注解支持包括Feign注解与JAX-RS注解,Feign还支持可插拔的编码器与解码器,Spring Cloud 增加了对 Spring MVC的注解,Spring Web 默认使用了HttpMessageConverters, Spring Cloud 集成 Ribbon 和 Eureka 提供的负载均衡的HTTP客户端 Feign。

GitHub地址:https://github.com/OpenFeign/feign

(1)导入依赖

<dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-starter-feign</artifactId>
       <version>1.4.7.RELEASE</version>
    </dependency>

(2)开启Feign功能

@SpringBootApplication
@EnableEurekaClient

//开启Feign功能
@EnableFeignClients 
public class OrderApp {

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

}

 

(3)修改ItemService逻辑

@FeignClient("app-item")
public interface ItemService {

    @PostMapping("/item")
    public Item queryItemById(@RequestParam("id") Long id);

 

    //Restful API调用

@PostMapping("/item/{id}")
    public Item queryItemById2(@RequestParam("id") Long id);



}

(4)使用ItemService

@RestController
public class OrderController {

    @Resource
    ItemService itemService;

    ...