Spring Cloud 入门 -- 搭建Eureka注册中心 实现服务者与消费者的服务调用

2022年05月13日 阅读数:4
这篇文章主要向大家介绍Spring Cloud 入门 -- 搭建Eureka注册中心 实现服务者与消费者的服务调用,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。


1、什么是Spring Cloud?

摘自Spring Cloud官网前端


Spring Cloud provides tools for developers to quickly build some of the common patterns in distributed systems (e.g. configuration management, service discovery, circuit breakers, intelligent routing, micro-proxy, control bus, one-time tokens, global locks, leadership election, distributed sessions, cluster state). Coordination of distributed systems leads to boiler plate patterns, and using Spring Cloud developers can quickly stand up services and applications that implement those patterns. They will work well in any distributed environment, including the developer’s own laptop, bare metal data centres, and managed platforms such as Cloud Foundry.java

以上翻译以下:mysql

Spring Cloud 为开发者提供了工具来快速构建分布式系统中的一些常见模式(例如配置管理、服务发现、断路器、智能路由、微代理、控制总线、一次性令牌、全局锁、领导选举、分布式会话,集群状态)。分布式系统的协调致使了样板模式,使用 Spring Cloud 开发人员能够快速创建实现这些模式的服务和应用程序。它们在任何分布式环境中都能很好地工做,包括开发人员本身的笔记本电脑、裸机数据中心以及 Cloud Foundry 等托管平台。web

Spring Cloud 入门 -- 搭建Eureka注册中心 实现服务者与消费者的服务调用_spring

大体意思就是 Spring Cloud 是一个分布式框架基于Spring Boot微服务,将一个一个独立的模块聚合,达到了“​​ 高内聚 · 低耦合​​ ”spring


2、Spring Cloud 与 Spring Boot 的关系

  • Spring Boot专一于开发方便的开发单个个体微服务;
  • Spring Cloud是关注全局的微服务协调整理治理框架,它将Spring Boot开发的一个个单体微服务,整合并管理起来,为各个微服务之间提供:配置管理、服务发现、断路器、路由、为代理、事件总栈、全局锁、决策竞选、分布式会话等等集成服务;
  • Spring Boot专一于快速、方便的开发单个个体微服务,Spring Cloud关注全局的服务治理框架
  • Spring Boot 能够离开Spring Cloud 独立运行,而Spring Cloud 不能够离开Spring Boot,是基于Spring Boot

3、Spring Cloud 与Dubbo 的区别

⛽服务的调用方式

Spring Cloud采用HTTP的REST方式调用服务,Dubbo采用RPC框架实现远程调用服务sql

⛽社区更新力度

Dubbo活跃度较低数据库

Spring Cloud社区活跃度比较高apache

定位不一样:Dubbo 的定位是一款高性能RPC框架,而Spring Cloud的目标是分布式微服务架构的一站式解决方案编程

框架 后端

Spring Cloud

Dubbo

服务注册中心

Spring Cloud Netfix Eureka

Zookkeper

服务调用方式

REST API

RPC

服务监控

Spring Boot Admin

Dubbo-monitor

断路器

Spring Cloud Netfix Hystrix

未完善,引用外部断路器

服务网关

Spring Cloud Netfix Zuul

分布式配置

Spring Cloud Config

服务跟踪

Spring Cloud Sleuth

消息总栈

Spring Cloud Bus

数据流

Spring Cloud Strem

批量任务

Spring Cloud Task

二者最大的区别:Spring Cloud 抛弃了 Dubbo 的 RPC,采用了基于 HTTP 的 REST方式

严格来讲,这两种方式各有优劣。虽然从必定程度上来讲,后者牺牲了服务调用的性能,但也避免了上面提到的原生RPC带来的问题。并且REST相比RPC更为灵活,服务提供方和调用方的依赖只依靠一纸契约,不存在代码级别的强依赖,这个优势在当下强调快速演化的微服务环境下,显得更加合适。

4、Spring Cloud 能干什么?

  • Distributed/versioned configuration 分布式/版本控制配置
  • Service registration and discovery 服务注册与发现
  • Routing 路由
  • Service-to-service calls 服务到服务的调用
  • Load balancing 负载均衡配置
  • Circuit Breakers 断路器
  • Distributed messaging 分布式消息管理

5、什么是Eureka?

Netflix在涉及Eureka时,遵循的就是API原则.

Eureka是Netflix子模块,也是核心模块之一。Eureka是基于REST的服务,用于定位服务,以实现云端中间件层服务发现和故障转移,服务注册与发现对于微服务来讲是很是重要的,有了服务注册与发现,只须要使用服务的标识符,就能够访问到服务,而不须要修改服务调用的配置文件了,功能相似于Dubbo的注册中心,好比Zookeeper。


6、Eureka 的特性及优势

  • Eureka是一个基于REST的服务,用于定位服务,以实现云端中间层服务发现和故障转移。
  • Eureka 主管服务注册与发现,在微服务中,之后了这二者,只须要使用服务的标识符,就是那个在每一个服务的yml文件中取得服务名称, 就能够访问到服务,不须要修改服务调用的配置文件。
  • Eureka遵循AP原则高可用,分区容错性,由于使用了自我保护机制因此保证了高可用。

Eureka两大组件:Eureka Server(提供注册服务)、 Eureka Client(JAVA客户端,负责发送心跳)

Eureka三大角色:

  • Eureka Server:提供服务注册和发现
  • Service Provider:服务提供方,将自身服务注册到Eureka,从而使服务消费方可以找到
  • Service Consumer:服务消费方,从Eureka获取注册服务列表,从而可以消费服务。

7、Spring Cloud入门案例 -- 搭建Eureka注册中心

✴️需求说明

基于Spring Boot聚合工程

使用Spring Cloud 实现分布式应用

  • 服务提供者,将服务注册到Eureka注册中心
  • 服务消费者,从Eureka取出调用的服务并获取返回结果

流程图Spring Cloud 入门 -- 搭建Eureka注册中心 实现服务者与消费者的服务调用_spring_02

❇️ 效果图

Spring Cloud 入门 -- 搭建Eureka注册中心 实现服务者与消费者的服务调用_spring_03

♻️项目结构

Spring Cloud 入门 -- 搭建Eureka注册中心 实现服务者与消费者的服务调用_spring_04

模块说明

  • spring_cloud模块:父级模块
  • springcloud-api:实体类模块
  • springcloud-eureka:注册中心模块
  • springcloud-provider:服务提供者模块
  • springcloud-consumer:服务消费者模块

⏳核心源码

⌚父级模块

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>org.example</groupId>
<artifactId>spring_cloud</artifactId>
<version>1.0-SNAPSHOT</version>
<modules>
<module>springcloud-api</module>
<module>springcloud-provider</module>
<module>springcloud-eureka</module>
<module>springcloud-consumer</module>
</modules>


<!-- 打包方式为 pom -->
<packaging>pom</packaging>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<junit.version>4.12</junit.version>
<log4j.version>1.2.17</log4j.version>
<lombok.version>1.16.18</lombok.version>
</properties>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>0.2.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--springCloud的依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--SpringBoot-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.4.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--数据库-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<!--SpringBoot 启动器-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<!--日志测试~-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
</dependencies>
</dependencyManagement>

</project>

⌚实体类模块

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>spring_cloud</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>springcloud-api</artifactId>

<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>

<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>

</project>

Dept实体类

package com.wanshi.springcloud.entity;

import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

@Data
@NoArgsConstructor
//支持链式编程
@Accessors(chain = true)
public class Dept {

private Integer dept_noid;

private String dept_name;

private String db_source;
}

⌚注册中心模块

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>spring_cloud</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>springcloud-eureka</artifactId>

<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka-server -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
<!-- 热部署工具 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>

</project>

application.yml

server:
port: 7001

# eureka 配置
eureka:
instance:
hostname: localhost # eureka 服务端的实例名称
client:
register-with-eureka: false # 是否向 eureka 注册本身,不注册本身
fetch-registry: false # fetch-registry 若是为false,表示本身为注册中心
service-url: # 将默认的url去掉,替换为本身的,监控页面
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

启动类

package com.wanshi.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
// EnableEurekaServer 启动Eureka服务
@EnableEurekaServer
public class EurekaServerMainApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerMainApplication.class, args);
}
}

⌚服务提供者模块

pom.xml

<dependencies>

<!-- Eureka -->
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>

<!-- actuator 监控中心 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>


<!-- 引入实体类 -->
<dependency>
<groupId>org.example</groupId>
<artifactId>springcloud-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>

<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>

<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>

<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>

<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>

<!-- test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- jetty -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>

<!-- 热部署工具 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>

</dependencies>

application.yml

server:
port: 8001
servlet:
context-path: /springcloud-provider-dept/

spring:
application:
name: SpringCloudProviderDept
datasource:
url: jdbc:mysql://localhost:3306/db_spring_cloud01
username: root
password: 111111
driver-class-name: com.mysql.jdbc.Driver


# Eureka的配置,服务注册到那里
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/
instance:
instance-id: springcloud-provider-dept8001 # 修改 Eureka上的默认描述信息

info:
app.name: wanshi-springcloud
company.name: blog.wanshi.com

DeptController

package com.wanshi.springcloud.controller;

import com.wanshi.springcloud.entity.Dept;
import com.wanshi.springcloud.service.DeptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/dept/")
public class DeptController {

@Autowired
private DeptService deptService;

@GetMapping("list")
public List<Dept> list() {
return deptService.list();
}

@PostMapping("insert")
public Integer insert(@RequestBody Dept param) {
return deptService.insert(param);
}

@PostMapping("get/{id}")
public Dept get(@PathVariable("id") Integer id) {
Dept param = new Dept();
param.setDept_noid(id);
return deptService.get(param);
}

}

⌚服务消费者模块

pom.xml

 <dependencies>

<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-ribbon -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>

<!-- Eureka -->
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>

<dependency>
<groupId>org.example</groupId>
<artifactId>springcloud-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- 热部署工具 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>

</dependencies>

application.yml

server:
port: 80

# Eureka配置
eureka:
client:
register-with-eureka: false # 不向注册中心注册本身
service-url:
defaultZone: http://localhost:7001/eureka/

ConfigBean配置

package com.wanshi.springcloud.config;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class ConfigBean {

@Bean
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}

DeptConsumerController

package com.wanshi.springcloud.controller;

import com.wanshi.springcloud.entity.Dept;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import java.util.List;

@RestController
@CrossOrigin
@RequestMapping("/consumer/dept/")
public class DeptConsumerController {

@Autowired
private RestTemplate restTemplate;

private static final String REST_URL_PREFIX = "http://localhost:8001/springcloud-provider-dept";

@GetMapping("get/{id}")
public Integer get(@PathVariable("id") Integer id) {
return restTemplate.getForObject(REST_URL_PREFIX + "/dept/get/" + id, Integer.class);
}

@GetMapping("list")
public List<Dept> list() {
return restTemplate.getForObject(REST_URL_PREFIX + "/dept/list", List.class);
}

@PostMapping("insert")
public Integer insert(@RequestBody Dept param) {
return restTemplate.patchForObject(REST_URL_PREFIX + "/dept/insert", param, Integer.class);
}
}

启动类

package com.wanshi.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

// Ribbon 和 Eureka 整合之后,客户端能够直接调用,不用关心IP地址和端口号
@SpringBootApplication
@EnableEurekaClient
public class DeptConsumerApplication {

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

8、源码下载

​Spring Cluod搭建Eureka注册中心实现服务者与消费者的服务调用​


⛵小结

以上就是【小王 Java】对Spring Cloud 搭建Eureka注册中心 实现服务者与消费者的服务调用 简单的概述,理解代码不难,多多练习,该工程是一个分布式应用框架,注册了Eureka注册中心做为服务的中转站,能够多多练习去巩固本身的技术~


若是这篇【文章】有帮助到你,但愿能够给【小王 Java】点个赞👍,创做不易,若是有对【后端技术】、【前端领域】感兴趣的小可爱,也欢迎关注❤️❤️❤️ 【小王 Java】❤️❤️❤️,我将会给你带来巨大的【收获与惊喜】💝💝💝!