微服务框架----Eureka 注册中心介绍和简单使用入门

Eureka 服务注册中心

服务注册中心是服务实现服务化管理的核心组件,类似于目录服务的作用,主要用来存储服务信息,譬如提供者url串、路由信息等,服务注册中心是微服务架构中最基础的设施之一。

在微服务架构流行之前,注册中心就开始出现分布式框架的系统。Dubbo是一个在国内比较流行的分布式框架,被大量的中小型互联网公司所采用,他提供比较完善的服务治理功能,而服务治理的实现主要依靠的就是注册中心。

学习目标:什么是注册中心,常见的注册中心,为什么需要注册中心,注册中心解决什么问题,什么是Eureka注册中心,Eureka注册中心三种角色,Eureka入门案例等

image-20210928102503756

1、什么是注册中心

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

服务注册中心的作用就是服务的注册和服务的发现。

服务发现:在通讯录里找到服务

服务注册:将服务存入通讯录里

2、常见的注册中心

  • Netflix Eureka
  • Alibaba Nacos
  • HashiCorp Consul
  • Apache ZooKeeper

image-20210926143352984

3、为什么需要注册中心

​ 在分布式系统中,我们不仅仅是需要注册中心找到服务和服务地址的映射关系那么简单,我们还需要考虑更多复杂的问题:

  • 服务注册后,如何被及时发现

  • 服务宕机后,如何及时下线

  • 服务如何有效的水平扩展

  • 服务发现时,如何进行路由

  • 服务异常时,如何进行降级

  • 注册中心如何实现自身的高可用

    这些问题的解决都依赖于注册中心。简单开,注册中心的功能有点类似于DNS服务器或者负载均衡器,而实际上,注册中心作为微服务的基础组件,可能要更加复杂,也需要更多的灵活性和时效性。所以我们还需要学习更多的Spring Cloud 微服务组件协同完成应用开发。

4、注册中心解决了什么问题

  • 服务管理
  • 服务的依赖关系管理

5、什么是Eureka注册中心

Eureka是Netflix开发的服务发现组件,本身是个基于REST的服务。Spring Cloud 将它集成在其子项目Spring Cloud Netflix 中,实现spring cloud的服务注册与发现,还提供了负载均衡、故障转移等能力。

6、Eureka注册中心三种角色

image-20210928112727805

6.1 Eureka Server

通过Register、Get、Renew等接口提供服务的注册和发现。

6.2 Application Server (Service Provider)

服务提供方,把自身的服务实例注册到Eureka Server中。

6.3 Application client (Service Consumer)

服务调用方,通过Eureka Server获取服务列表,消费服务。

image-20210926144916618

image-20210926145144410

7、Eureka 入门案例

7.1 创建项目

采用聚合项目来讲解Eureka,首先创建一个pom父工程。

image-20210928145911071

image-20210928150011110

image-20210928150144614

7.2 父 pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.xxxx</groupId>
    <artifactId>eureka-demo</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>eureka-server</module>
    </modules>

    <!-- 继承spring-boot-starter-parent 依赖    -->
    <!-- 使用继承方式 实现复用 符合继承的都可以被使用 -->
    <parent>
        <artifactId>spring-boot-starter-parent</artifactId>
        <groupId>org.springframework.boot</groupId>
        <version>2.3.12.RELEASE</version>
    </parent>

    <!--
        集中定义依赖组件版本号,但不引入
        在子工程中用到声明的依赖时,可以不加依赖的版本号
        这样可以统一管理工程中用到的依赖版本
    -->
    <properties>
       <spring-cloud.version>Hoxton.SR1</spring-cloud.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>
   <!-- 项目依赖管理  父项目只是声明依赖  子项目需要写明需要的依赖 可以省略版本信息-->
    <dependencyManagement>
        <dependencies>
            <!-- spring cloud 依赖-->
            <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-dependencies -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

</project>

spring-boot-starter-parent 是 Spring Boot 的父级依赖,这样当前的项目就是 Spring Boot 项目了。spring-boot-starter-parent 是一个特殊的 starter,它用来提供相关的 Maven 默认依赖。使用它之后,常用的包依赖可以省去 version 标签

7.3 创建子模块

7.3.1 创建子模块server服务端

image-20210928160442686

image-20210928162935859

7.3.2 子模块 server 配置文件

application.yml

server:
  port: 8761  #端口
spring:
  application:
    name: eureka-server  #应用名称
# 配置Eureka Server 注册中心

eureka:
  instance:
    hostname: localhost  # 主机名 不配置的时候将根据操作系统的主机名来获取

  client:
    register-with-eureka: false   # 是否将自己注册到注册中心,默认为true  如果是单体应用 则不需要注册
    fetch-registry: false    #  是否从注册中心获取服务注册信息  默认为true
    service-url:   # 注册中心对外暴露的注册地址
      defaultZone:
        http://${eureka.instance.hostname}:${server.port}/eureka/
      defaultZone:http://${eureka.instance.hostname}:${server.port}/eureka/

eureka默认开启将自己注册到注册中心,如果应用是单节点,要关闭着两个配置register-with-eureka、

fetch-registry。

7.3.3 server的启动类

EurekaServerApplication.java

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

注意:@EnableEurekaServer 使用注解开启eureka注册中心。

7.3.4 server的pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <!-- 继承父依赖 -->
    <parent>
        <artifactId>eureka-demo</artifactId>
        <groupId>com.xxxx</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>eureka-server</artifactId>

    <!-- 项目依赖 -->
    <dependencies>
        <!-- eureker server 依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>

        <!-- spring boot test依赖 因为父pom.xml已经引入boot-->
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
7.3.5 效果

访问连接localhost:8761

image-20210929153337681

8、Eureka 注册中心、服务提供者、消费者建立

8.1注册中心

(可建立两个eureka注册中心)

暂时采用一个eureka注册中心,过程如7所示。

8.2 服务提供者

8.2.1 pom.xml
<dependencies>
    <!-- netflix eureka client 依赖 -->
    <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-eureka-client -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
    <!-- spring boot web 依赖-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- lombok 依赖-->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.18</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

</dependencies>
8.2.2 application.yml
server:
  port: 7070 #端口
spring:
  application:
    name: service-provider #应用名称
eureka:
  instance:
    prefer-ip-address: true   #是否使用ip地址注册
    instance-id: ${spring.cloud.client.ip-address}:${server.port} # id :port
  client:
    service-url:
      defaultZone:    #设置服务注册中心地址
        http://localhost:8761/eureka/
8.2.3 实体类和服务

1、实体类

com.xxxx.pojo包下 production.java

package com.xxxx.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.yaml.snakeyaml.events.Event;

import java.io.Serializable;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Production  implements Serializable {
    private Integer id;
    private String productName;
    private Integer productNum;
    private Double productPrice;

}
Serializable  序列化

Serializable 序列化

序列化:对象的寿命通常随着生成该对象的程序的终止而终止,有时候需要把在内存中的各种对象的状态(也就是实例变量,不是方法)保存下来,并且可以在需要时再将对象恢复。虽然你可以用你自己的各种各样的方法来保存对象的状态,但是Java给你提供一种应该比你自己的好的保存对象状态的机制,那就是序列化。

总结:Java 序列化技术可以使你将一个对象的状态写入一个Byte 流里(系列化),并且可以从其它地方把该Byte 流里的数据读出来(反序列化)。

序列化 的用途

  • 想把的内存中的对象状态保存到一个文件中或者数据库中时候
  • 想把对象通过网络进行传播的时候

2、service服务类和实现类

package com.xxxx.service;

import com.xxxx.pojo.Production;


import java.util.List;

/**
 * @author xuan
 */
public interface ProductService {
    /**
     * 查询商品列表
     * @return
     */
    List<Production> selectProductionList();
}

实现类

package com.xxxx.service.impl;


import com.xxxx.pojo.Production;
import com.xxxx.service.ProductService;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;

/**
 * @author xuan
 */
@Service
public class ProductServiceImpl implements ProductService {
    @Override
    public List<Production> selectProductionList(){
        return Arrays.asList(
                new Production(1,"华为手机",2,5888D),
                new Production(2,"联想笔记本",1,6888D),
                new Production(3,"小米平板",5,2666D)
        );
    }
}
8.2.4 controller
package com.xxxx.controller;

import com.xxxx.pojo.Production;
import com.xxxx.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * @author xuan
 */
@RestController
@RequestMapping("/product")
public class ProductController {
    @Autowired
    private ProductService productService;

    @GetMapping("/list")
    public List<Production> selectProductList(){
        return productService.selectProductionList();
    }
}
8.2.5 启动类
@SpringBootApplication
@EnableEurekaClient
public class EurekaProviderApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaProviderApplication.class,args);
    }
}

8.3 消费者

8.3.1 pom.xml
<dependencies>
    <!-- netflix eureka client 依赖 -->
    <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-eureka-client -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
    <!-- spring boot web 依赖-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- lombok 依赖-->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.18</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>


</dependencies>
8.3.2 application.yml
server:
  port: 9090 #端口
spring:
  application:
    name: service-consumer #应用名称
eureka:
  client:
    service-url:
      defaultZone:    #设置服务注册中心地址
        http://localhost:8761/eureka/
    register-with-eureka: false  #不将服务注册到注册中心
    registry-fetch-interval-seconds: 30  #每30秒拉取一次服务列表
8.3.3 实体类和服务

1、实体类

produc.java

@Data
@NoArgsConstructor
@AllArgsConstructor

public class Product implements Serializable {
    private Integer id;
    private String productName;
    private Integer productNum;
    private Double productPrice;
}

order.java

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Order implements Serializable {
    private  Integer id;
    private  String orderNo;
    private  String orderAddress;
    private  Double totalPrice;
    private List<Product> productList;
}

2、服务类

服务接口

package com.xxxx.service;

import com.xxxx.pojo.Order;

public interface OrderService {
    /**
     * 根据主键查询订单
     * @param id
     * @return
     */
    Order selectOrderById(Integer id);
}

服务实现类 OrderServiceImpl.java

package com.xxxx.service.impl;

import com.xxxx.pojo.Order;
import com.xxxx.pojo.Product;
import com.xxxx.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.client.RestTemplate;

import java.util.List;
@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private DiscoveryClient discoveryClient;

    /**
     * 根据主键查询订单
     * @param id
     * @return
     */
    @Override
    public Order selectOrderById(Integer id){
        return new Order(id,"order-001","中国",31994D,
                selectProductListByDiscoveryClient());
    }

    private List<Product> selectProductListByDiscoveryClient(){
        StringBuffer sb = null;

        // 获取服务列表
        List<String> serviceIds = discoveryClient.getServices();
        //collectionutils 集合判断是否为空
        if (CollectionUtils.isEmpty(serviceIds)) {
            return null;
        }

        // 根据服务名称获取服务
        List<ServiceInstance> serviceInstances = discoveryClient.getInstances("service-provider");
        if(CollectionUtils.isEmpty(serviceInstances)) {
            return null;
        }
        //instance 实例
        ServiceInstance si = serviceInstances.get(0);
        sb = new StringBuffer();
        sb.append("http://"+si.getHost()+":"+si.getPort()+"/product/list");

        //ResponseEntity 封装了返回数据
        ResponseEntity<List<Product>> response = restTemplate.exchange(
                sb.toString(),
                HttpMethod.GET,
                null,
                new ParameterizedTypeReference<List<Product>>() {}
        );
        return response.getBody();
    }
}

重点代码是:获取服务列表,根据服务名称获取服务(为集合),根据服务的url获取封装的数据。

8.2.4 controller
@RestController
@RequestMapping("/order")
public class OrderController {
    @Autowired
    private OrderService orderService;

    @GetMapping("/{id}")
    public Order selectOrderById(@PathVariable("id") Integer id){
        return orderService.selectOrderById(id);

    }
}
8.2.5 启动类
@EnableEurekaClient
@SpringBootApplication
public class EurekaConsumerApplication {
    @Bean
    public RestTemplate restTemplate(){
        return  new RestTemplate();
    }
    public static void main(String[] args) {
        SpringApplication.run(EurekaConsumerApplication.class,args);
    }
}

总结:最主要是学会消费者,client如何获取服务列表和内容,拼接数据。
将三个项目都启动,访问消费者的接口
localhost:9090/order/1 可以获取远程接口localhost:7070/product/list信息。
http://localhost:8761

image-20211008123310676

http://localhost:9090/order/1

image-20211008123341153

http://localhost:7070/product/list

image-20211008123445500

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Cloud 是一个用于构建微服务架构的开源框架,它提供了一系列的解决方案和工具,帮助开发者快速构建和管理分布式系统。 以下是一个简单的 Spring Cloud 入门示例代码: 1. 创建服务注册中心Eureka Server): ```java @SpringBootApplication @EnableEurekaServer public class EurekaServerApplication { public static void main(String[] args) { SpringApplication.run(EurekaServerApplication.class, args); } } ``` 2. 创建服务提供者(Eureka Client): ```java @SpringBootApplication @EnableDiscoveryClient public class ServiceProviderApplication { public static void main(String[] args) { SpringApplication.run(ServiceProviderApplication.class, args); } } @RestController class HelloController { @GetMapping("/hello") public String hello() { return "Hello, Spring Cloud!"; } } ``` 3. 创建服务消费者(Eureka Client): ```java @SpringBootApplication @EnableDiscoveryClient public class ServiceConsumerApplication { public static void main(String[] args) { SpringApplication.run(ServiceConsumerApplication.class, args); } } @RestController class HelloController { @Autowired private RestTemplate restTemplate; @GetMapping("/hello") public String hello() { String serviceUrl = "http://service-provider/hello"; return restTemplate.getForObject(serviceUrl, String.class); } } @Configuration class RestTemplateConfig { @Bean public RestTemplate restTemplate() { return new RestTemplate(); } } ``` 以上示例代码演示了使用 Spring Cloud 构建一个简单微服务架构,其中包括服务注册中心Eureka Server)、服务提供者(Eureka Client)和服务消费者(Eureka Client)。服务提供者注册到服务注册中心,服务消费者通过服务注册中心发现并调用服务提供者的接口。 希望以上示例能够帮助你快速入门 Spring Cloud。如果有任何问题,请随时提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值