springCloud教程(二)---服务注册与发现Eureka

一 什么是注册中心

      注册中心相当于微服务架构中的”通讯录“,它记录了服务和服务地址的映射关系。在分布式架构中,服务会注册到这里,当服务需要调用其它服务时,就这里找到服务的地址,进行调用。

注册中心主要涉及到三大角色:

  1. 服务提供者
  2. 服务消费者
  3. 注册中心

它们之间的关系大致如下:

  1. 各个微服务在启动时,将自己的网络地址等信息注册到注册中心,注册中心存储这些数据。

  2. 服务消费者从注册中心查询服务提供者的地址,并通过该地址调用服务提供者的接口。

  3. 各个微服务与注册中心使用一定机制(例如心跳)通信。如果注册中心与某微服务长时间无法通信,就会注销该实例。

在没有注册中心时候,服务间调用需要知道被调方的地址或者代理地址。当服务更换部署地址,就不得不修改调用当中指定的地址或者修改代理配置。当有更多的服务的时候,对后期的维护管理成本太高,操作麻烦。而有了注册中心之后,每个服务在调用别人的时候只需要知道服务名称就好,继续地址都会通过注册中心同步过来。

为了更好的理解其实生活中好多类似注册中心的例子,打个比方:以前我在大学时候,还没有饿了吗美团的时候,点外卖需要去记录各个餐饮店的外卖电话,然后需要的时候会拨打电话去点外卖。有时候还会拨错电话。但是当有了美团饿了吗的时候,这个时候我们不需要去记录各个外卖店的电话,我们只需要知道这家店的店名下单即可。此时外卖平台就相当于注册中心,外卖商家作为服务提供者一方,而我们就是消费者一方。这时候注册中心的作用就显而易见了。

二 搭建Eureka注册中心

1.创建pom项目

      

     第一次创建后,导入的jar包较多,静候一段时间,等待项目创建完成。

pom.xml

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

这里会出现springcloud与springboot的版本契合问题,可以看官方文档,官方文档上都有说明,个人心得:任何时候学习新东西,官方文档是必看的,官方文档就像一个产品的说明书,附上官方文档地址:https://spring.io/projects/spring-cloud

  我这里使用的是目前springcloud最新的版本

<spring-cloud.version>Hoxton.SR8</spring-cloud.version>

官方文档给出的说明:

个人采用的是Boot Version:2.3.5+Cloud Version:Hoxton.SR8

2  配置application

一. Standalone Mode(独立模式)

所谓的独立模式就是只配置一个注册中心,配置application.yml如下:

server:
  port: 8761
eureka:
  instance:
    hostname: localhost #应用实例主机名
  client:
    registerWithEureka: false #表示自己就是注册中心,不用注册自己
    fetchRegistry: false  #表示自己就是注册中心,不用去注册中心获取其他服务的地址
    serviceUrl:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

spring:
  application:
    name: eurka-server

添加@EnableEurekaServer 注解

@SpringBootApplication
@EnableEurekaServer
public class ServerApplication {

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

}

启动,在浏览器输入配置的地址端口,localhost:8761


 

二 .Peer Awareness(对等模式)

官方文档解释:

Eureka can be made even more resilient and available by running multiple instances and asking them to register with each other. In fact, this is the default behavior, so all you need to do to make it work is add a valid serviceUrl to a peer

翻译过来的大致意思是:

通过运行多个实例并要求它们彼此注册,Eureka可以变得更具灵活和可用性。Eureka Server的高可用实际上就是将自己作为服务向其他服务注册中心注册自己,这样就可以形成一组互相注册的服务注册中心,以实现服务清单的互相同步,当其中一个注册中心挂掉,另一个就会启用,服务就不会一次宕掉,达到高可用的效果。

(1)application.yml (Two Peer Aware Eureka Servers)

如果是两个注册中心的,可以定义application-peer1,application-peer2

application-peer1:

server:
  port: 8761
eureka:
  instance:
    hostname: peer1 #应用实例主机名
    prefer-ip-address: true #以ip地址访问
  client:
    register-with-eureka: true # 当然这个默认就是true,表示向eureka注册自己
    fetch-registry: true # 这个的意思是从eureka server拉取注册表,集群中从相邻的eureka server拉取注册表
    serviceUrl:
      defaultZone: http://localhost:8762/eureka

spring:
  profiles: peer1
  application:
    name: eureka-server

application-peer2:

server:
  port: 8762
eureka:
  instance:
    hostname: peer2 #应用实例主机名
    prefer-ip-address: true
  client:
    register-with-eureka: true # 这个默认就是true,表示向eureka注册自己
    fetch-registry: true # 默认是true,这个的意思是从eureka server拉取注册表,集群中从相邻的eureka server拉取注册表
    serviceUrl:
      defaultZone: http://localhost:8761/eureka

spring:
  profiles: peer2
  application:
    name: eureka-server

官方文档上是用hostname替代localhost,然后在etc/hosts中添加映射解析,它也说了In fact, the eureka.instance.hostname is not needed if you are running on a machine that knows its own hostname,如果自己知道是哪台机器在运行就行了,毕竟是测试环境。所以自己知道就行。

启动完成后:同时将自己下面创建的订单服务也注册到注册中心进行测试,(用idea来模拟同时两个注册中心同时启动的话,可以进行下面设置,勾选allow parallel run 同时profiles输入peer1或peer2进行测试

 

三个服务启动完成后,访问localhost:8761与localhost:8762

然后当我关闭8761服务后,8762照样可以访问

关闭8761后,8762界面访问时候并没有马上移除8761服务,这里涉及到一个自我保护机制,默认情况下,如果Eureka Server在一定时间内(默认90秒)没有接收到某个微服务实例的心跳,Eureka Server将会移除该实例。想在测试环境演示快速移除失效的服务,可以这么做。

服务端配置:

eureka:
  server:
 # 测试时关闭自我保护机制,保证不可用服务及时踢出,生产机不建议关闭
  enable-self-preservation: false
 #eureka服务器在接受到实力的最后一次发出的心跳后,需要等待多久才可以将此实力删除
  lease-expiration-duration-in-seconds: 10

客户端配置:

eureka:
    instance:
        lease-renewal-interval-in-seconds: 1 # 每间隔1s,向服务端发送一次心跳,证明自己依然”存活“。
        lease-expiration-duration-in-seconds: 2 #告诉服务端,如果我2s之内没有给你发心跳,就代表我“死”了,将我踢出掉。

最后你会发现只剩一个订单服务了。因为两个注册中心是相互注册的,所以当一个挂掉,另一个也会随之挂掉。A注册了B,B又注册了A,所以A跟B的注册列表是一样的。A中有B,B中又有A,这样做的目的是对注册中心的监控,当A注册中心宕机,A在一段时间内并没有给B发送心跳检测,后续就可以通过eureka监听器来监听是否宕机然后设置邮件提醒功能

 

三 创建商品服务

模拟商品与订单服务调用,新建一个商品服务来模拟服务注册,订单服务就可以调用商品服务来获取商品的相关数据。

1.创建pom项目

pom.xml

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

模拟基础的订单服务,省略数据库操作层

model:

package com.eureka.product_service.model;

import java.io.Serializable;
import java.math.BigDecimal;

public class Product implements Serializable {

    /**
     * 商品id
     */
    private Long id;

    /**
     * 商品名称
     */
    private String  productName;

    /**
     * 商品价格
     */
    private BigDecimal price;

    /**
     * 商品数量
     */
    private Integer storeNumber;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getProductName() {
        return productName;
    }

    public void setProductName(String productName) {
        this.productName = productName;
    }

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }

    public Integer getStoreNumber() {
        return storeNumber;
    }

    public void setStoreNumber(Integer storeNumber) {
        this.storeNumber = storeNumber;
    }
}

service:

@Service
public class ProductServiceImpl implements ProductService {
    private final static Map<Long, Product> map=new HashMap<>();

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

    /**
     * 初始化模拟用户数据
     *
     */
    static {
        Product product1=new Product();
        product1.setId(1L);
        product1.setProductName("电脑");
        product1.setPrice(new BigDecimal(5000));
        product1.setStoreNumber(100);

        Product product2=new Product();
        product2.setId(2L);
        product2.setProductName("电视");
        product2.setPrice(new BigDecimal(2000));
        product2.setStoreNumber(50);

        map.put(product1.getId(),product1);
        map.put(product2.getId(),product2);

    }

    @Override
    public List<Product> productList() {
        List<Product> products=new ArrayList<Product>(map.values());
        return products;
    }

    @Override
    public Product getOneProduct(Long id) {

        /**
         * 省略数据库查询操作
         */
        Product product=map.get(id);
        return  product;
    }

    @Override
    public Collection<Product> saveProduct(Product product) {
         map.put(product.getId(),product);
         return  map.values();
    }

controller:

@RestController
@RequestMapping("/api")
public class ProductController {


    @Autowired
    private ProductService productService;


    /**
     * 获取所有的订单信息
     * @return
     */
    @GetMapping("/products")
    public List<Product> getProductList() {
        return productService.productList();
    }

    /**
     * 查询单个订单
     * @return
     */
    @GetMapping("/product/{id}")
    public Product getProduct(@PathVariable Long id) {
        return productService.getOneProduct(id);
    }



}

2.配置application文件

server:
  port: 8881
spring:
  application:
    name: productService

eureka:
  client:
    serviceUrl: #将订单服务注册到注册中心
      defaultZone: http://localhost:8761/eureka/
    enabled: true  #默认是开启,false表示不注册到eureka

首先启动注册中心服务,然后启动订单服务,查看效果

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值