【SpringCloud】05 Eureka 02 高可用与集群

 

 

Eureka集群环境搭建:

新建Eureka集群模块,模块名称:Eureka-Cluster-Server-Port-7002

导入7001依赖坐标:

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>cn.dzz.springcloud</groupId>
        <artifactId>API-Commons</artifactId>
        <version>${project.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

Host文件地址:

C:\Windows\System32\drivers\etc

修改Host文件:

# Copyright (c) 1993-2009 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example:
#
#      102.54.94.97     rhino.acme.com          # source server
#       38.25.63.10     x.acme.com              # x client host
# localhost name resolution is handled within DNS itself.
#    127.0.0.1       localhost
#    ::1             localhost
127.0.0.1 steamcommunity.com #S302

127.0.0.1 www.steamcommunity.com #S302

127.0.0.1       localhost.lodop.net
127.0.0.1       activate.navicat.com
127.0.0.1       eureka7001.cn   # 2020.08.25
127.0.0.1       eureka7002.cn   # 2020.08.25

配置Application.yml文件

server:
  port: 7002
eureka:
  instance:
    hostname: eureka7002.cn
  client:
    fetch-registry: false
    register-with-eureka: false
    service-url:
      defaultZone: http://eureka7001.cn:7001/eureka/

互相注册,相互守望

YML配置相互更换服务地址:

server:
  port: 7001
eureka:
  instance:
    hostname: eureka7001.cn
  client:
    fetch-registry: false
    register-with-eureka: false
    service-url:
      defaultZone: http://eureka7002.cn:7002/eureka/

编写主启动类:

package cn.dzz.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

/**
 * @author DaiZhiZhou
 * @file SpringCloud-ATGG-2020
 * @create 2020-08-25 16:03
 */
@SpringBootApplication
@EnableEurekaServer
public class EurekaClusterServerPort7002Application {

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

访问7002端口

http://eureka7002.cn:7002/

访问7001端口

http://eureka7001.cn:7001/

使用原始的这个localhost也可以是运行的

http://localhost:7001/
http://localhost:7002/

提供者支付模块和消费者订单模块注册到Eureka集群服务中心:

注册接口地址追加集群服务接口:

8001

eureka:
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka/,http://eureka7002.cn:7002/eureka/
    register-with-eureka: true
    fetch-registry: true

80

eureka:
  client:
    fetch-registry: true
    register-with-eureka: true
    service-url:
      defaultZone: http://localhost:7001/eureka/,http://eureka7002.cn:7002/eureka/

程序启动顺序

第一:服务中心必须先开启,7001 & 7002 这个集群内的先后顺序可以部分

第二:提供者8001开启

第三:消费者80开启

 

启动后访问服务,测试是否正常:

http://localhost/order/consumer/payment/get/2

访问7001可以发现服务都被注册到了

http://localhost:7001/

 

提供者支付模块集群

现在只是一个提供者支付模块,而我们需要搭建这个提供者支付模块集群

1、创建新模块,模块名称:Provider-Payment-Port-8002

2、Pom的坐标依赖与8001一致

3、application.yml和启动类更换下端口号8002

4、支付模块的集群都使用了Provider-Payment-Service作为服务名称,但是端口并不一致

 

更改8001模块的Controller配置:

获取端口号用于区分我们的模块调用,同理粘贴8002模块一份

package cn.dzz.springcloud.controller;

import cn.dzz.springcloud.component.JsonResult;
import cn.dzz.springcloud.entity.Payment;
import cn.dzz.springcloud.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;

/**
 * @author ArkD42
 * @file SpringCloud-ATGG-2020
 * @create 2020年08月24日 21:28
 */
@RestController
@Slf4j
@RequestMapping("payment")
public class PaymentController {
    @Resource
    private PaymentService paymentService;

    @Value("${server.port}")
    private String serverPort;

    @PostMapping("create")
    public JsonResult<Object> createPayment(@RequestBody Payment payment){
        int result = paymentService.addPayment(payment);
        log.info("插入操作结果:" + result);
        if (result > 0) return new JsonResult<Object>(200, "插入数据成功, 端口:" + serverPort, result);
        return new JsonResult<Object>(500, "插入数据失败 端口:" + serverPort, result);
    }
    @GetMapping("get/{id}")
    public JsonResult<Payment> getPaymentById(@PathVariable("id") Long id){
        Payment paymentById = paymentService.getPaymentById(id);
        log.info("查询操作结果:" + paymentById + "用来测试热部署的修改");
        if (paymentById != null) return new JsonResult<Payment>(200, "查询数据成功  端口:" + serverPort, paymentById);
        return new JsonResult<Payment>(500, "查询数据失败  端口:" + serverPort, null);
    }
}

 

启动所有服务模块,查看Eureka界面:

http://eureka7001.cn:7001/

同理7002也是一样

 http://eureka7002.cn:7002/

然后测试8002端口号:

http://localhost:8002/payment/get/2
{"code":200,"message":"查询数据成功  端口:8002","data":{"id":2,"serial":"aaabbb222"}}

原先的8001端口也正常:

http://localhost:8001/payment/get/2
{"code":200,"message":"查询数据成功  端口:8001","data":{"id":2,"serial":"aaabbb222"}}

但是通过消费者订单模块调用的时候,始终访问的都是8001端口模块的:

http://localhost/order/consumer/payment/get/2
{"code":200,"message":"查询数据成功  端口:8001","data":{"id":2,"serial":"aaabbb222"}}

这是因为订单模块控制器固定写死了8001的接口调用:

但是我们是希望集群的每一个都能被订单模块调用,所以通过Eureka我们应该使用注册中心的服务名称来实现

我们的集群共用了一个服务名称,通过服务名称,Eureka来自动帮助我们寻找集群的某一服务

// 单机单一模块调用  public static final String PAYMENT_URL = "http://localhost:8001";
// 集群调用则使用共同的服务名称来实现 public static final String PAYMENT_URL = "http://PROVIDER-PAYMENT-SERVICE";

 

重启所有服务之后,再次调用报错:

Caused by: java.net.UnknownHostException: PROVIDER-PAYMENT-SERVICE

服务并不知道这个名称是指向什么主机地址,发现Eureka不能像Nginx那样,

反向代理多少个集群就会自动分配权重,实现负载均衡

这里还需要我们来配置RestTemplate负载均衡:

打上@LoadBalanced注解

现在可以访问8002端口下的调用了:

http://localhost/order/consumer/payment/get/2
"code":200,"message":"查询数据成功  端口:8002","data":{"id":2,"serial":"aaabbb222"}}

 

Actuator服务信息完善:

对8001 & 8002 端口设置信息:

eureka:
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka/,http://eureka7002.cn:7002/eureka/
    register-with-eureka: true
    fetch-registry: true
  instance:
    instance-id: provider-payment-service-port-8001

 

访问Eureka界面,会发现我们的地址显示会换成ID显示

但是还好上面的没有替换

http://eureka7002.cn:7002/

当然80订单模块还没有配置,只显示了地址和服务名称

如需要查看具体IP地址,可以再配置这个属性,Eureka将不再显示ID名称,而是IP:

eureka:
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka/,http://eureka7002.cn:7002/eureka/
    register-with-eureka: true
    fetch-registry: true
  instance:
    instance-id: provider-payment-service-port-8002
    prefer-ip-address: true

之后我们把光标扶上ID的时候,浏览器的左下角就会显示

这个IP地址:

 

posted @ 2020-08-25 23:35  emdzz  阅读(320)  评论(0)    收藏  举报