前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring Cloud 组件快速入门

Spring Cloud 组件快速入门

作者头像
leon_橙
发布2020-03-02 15:28:22
1.9K0
发布2020-03-02 15:28:22
举报
文章被收录于专栏:Java后台Java后台

组件简介

spring cloud 是基于 springboot 基础之上构建的一系列分布式微服务组件集,其组件主要包括:

  • Eureka 微服务注册发现中心
  • Feign 微服务远程调用
  • Ribbon 微服务客户端之间负载均衡器
  • Config server 微服务配置中心
  • Zuul 微服务调用网关
  • Hystrix 微服务调用熔断降级

spring cloud 提供的是一整套的开源分布式微服务解决方案。当然,随着业务发展的瓶颈,各家都会 “因地制宜” 自研对应的替代组件,像阿里的 Dubbo rpc 框架,以 zookeeper 为注册中心。携程的 Apollo 配置中心。腾讯的 tRPC,七彩石远程配置中心等等。相对而言,spring cloud 组件更易上手,有利于对分布式微服务解决方案有个大致的概念。

Eureka Server

Eureka 是 spring cloud 的微服务注册发现中心,所有的微服务只有服务注册中心注册后才能被其他服务远程调用,注册到 Eureka 的微服务会定时收到心跳信号,但服务异常时会被注册中心下线。下面我们首先实现一个简单服务注册发现中心。

首先搭建最基础的 spring boot 工程,引入 Eureka 组件依赖,最终的 maven 依赖如下 (pom.xml):

Eureka Server 依赖文件

代码语言:javascript
复制
<?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>www.gaiserchan.test</groupId>
    <artifactId>eureka-test</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.10.RELEASE</version>
    </parent>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.1.10.RELEASE</version>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-undertow</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            <version>2.1.4.RELEASE</version>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Greenwich.SR4</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

项目工程结构如图所示

Eureka Server 配置文件

修改项目配置文件 (application.properties)

代码语言:javascript
复制
# 服务名称
spring.application.name=eureka-server
# 服务端口号
server.port=20200
# 注册中心实例地址
eureka.instance.hostname=localhost
# 是否注册到注册中心
eureka.client.register-with-eureka=false
# 屏蔽注册中心
eureka.client.fetch-registry=false

编写 spring boot 启动代码 (Application.java)

Application.java

代码语言:javascript
复制
package www.eureka.test;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
/**
 * @author gaiserchen
 * @date 2020.02.20
 * spring boot 应用启动注解
 */
@SpringBootApplication
@EnableEurekaServer
public class Application {
    public static void main (String [] args){
        SpringApplication.run (Application.class,args);
    }
}

运行程序 'Run Application.main ()'

程序启动后访问 <http://localhost:20200> 可以看到如下界面,我们的第一个服务注册发现中心就启动成功了。

Eureka Server 启动结果

可以看到,此时注册中心是没有任何微服务注册到注册中心的,下面我们写一个简单的 web 服务,并注册到服务注册中心。

Eureka client

所有基于 spring boot 框架构建的 web 程序,只要注册到服务注册中心,都可以称之为提供 web 服务的 “Eureka client”。

同样,我们先搭建一个最简单的 spring boot 工程,引入 eureka client 组件,最终的 maven 依赖如下:

Eureka client 依赖文件

代码语言:javascript
复制
<?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>www.eureka.test</groupId>
    <artifactId>eureka-client</artifactId>
    <version>1.0-SNAPSHOT</version>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.10.RELEASE</version>
    </parent>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.1.10.RELEASE</version>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-undertow</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            <version>2.1.4.RELEASE</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

工程项目结构如图所示:

Eureka client 配置文件

修改对应工程的配置文件 (application.properties), 填写对应的服务注册中心地址。

代码语言:javascript
复制
# 服务名称
spring.application.name=eureka-client
# 服务端口
server.port=20201
# 注册中心地址
eureka.client.serviceUrl.defaultZone=http://localhost:20200/eureka/

eureka client 的测试代码中我们主要编写 Application.java 和 Sample.java

所有 spring boot 工程的 Application.java 的代码都类似,主要的系统接口在 controller 层编写。

Application.java

代码语言:javascript
复制
package com.eureka.client;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
/**
 * @author gaiserchen
 * @date 2020.02.20
 * spring boot 应用启动注解
 */
@SpringBootApplication
@EnableEurekaClient
public class Application {
    public static void main (String [] args) {
        SpringApplication.run (Application.class, args);
    }
}

controller/Sample.java, 这里的逻辑是,直接获取配置文件里的 spring.application.name 和 server.port 变量然后返回。

代码语言:javascript
复制
package com.eureka.client.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
 * @author gaiserchen
 * @date 2020.02.20
 * sample controller
 */
@RestController
public class Sample {
    @Value ("${server.port}")
    String port;
    @Value ("${spring.application.name}")
    String applicationName;
    @GetMapping (value = "/sample")
    public String sample (@RequestParam (value = "name", defaultValue = "gaiserchen") String name) {
        return "hello" + name + ", i am from:" + applicationName + ", and port is:" + port;
    }
}

Eureka client 启动结果

同样,启动程序之后,我们直接访问 <http://localhost:20201>,其结果如图:

这时,我们再访问 Eureka Server 的地址 <http://localhost:20200>,可以看到此时的服务注册中心已经有注册的应用服务。

Feign 远程调用

在前面我们已经构建好一个 web 应用,并且已经注册到注册中心,下面我们可以通过 Feign 远程调用组件获取接口数据。

我们再次构建一个 springboot 应用,引入 feign 组件依赖,项目最终的 maven 如下:

Feign 依赖文件

代码语言:javascript
复制
<?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.eureka.feign</groupId>
    <artifactId>eurekaFeign</artifactId>
    <version>1.0-SNAPSHOT</version>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.10.RELEASE</version>
    </parent>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.1.10.RELEASE</version>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-undertow</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
            <version>1.4.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
            <version>1.4.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
            <version>1.4.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Greenwich.SR4</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

工程项目结构如图所示:

Feign 配置文件

修改配置文件,因为是远程调用其他服务,所以当其他远程服务异常时需要有一定的服务熔断处理,所以这里启用了 hystrix 服务熔断组件。

application.properties

代码语言:javascript
复制
# 服务名称
spring.application.name=service-feign
# 服务端口
server.port=20202
# 服务注册中心地址
eureka.client.serviceUrl.defaultZone=http://localhost:20200/eureka/
# hystrix 服务熔断降级启用
feign.hystrix.enabled=true

这次我们需要编写 feign 工程自己的接口层逻辑,接口拿到请求值 name, 具体处理逻辑在 service 层。

controller/FeignController.java

代码语言:javascript
复制
package com.feign.test.controller;
import com.feign.test.service.FeignService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
 * @author gaiserchen
 * @date 2020.02.02
 * feign controller
 */
@RestController
public class FeignController {
    @Autowired
    FeignService feignService;
    
    @GetMapping ("/feign-consumer")
    public String feignConsumer (@RequestParam (defaultValue = "gaiserchan") String name) {
        return feignService.feignConsumer (name);
    }
}

下面编写我们 service 层的业务处理逻辑,service 接口引入了 @FeignClient 注解,这个注解直接启用 Feign 组件,value 填需要调用的远程服务名 spring.application.name,fallback 是当远程服务调用异常需要做哪些异常处理,在具体业务逻辑中,直接拿上一步取到的 name 值远程调用 eureka-client 的 sample 接口。

service/FeignService.java

代码语言:javascript
复制
package com.feign.test.service;
import com.feign.test.service.impl.FeignHystricServiceImpl;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
 * @author gaiserchen
 * @date 2020.02.20
 * feign client
 */
@FeignClient (value = "eureka-client", fallback = FeignHystricServiceImpl.class)
public interface FeignService {
    @GetMapping (value = "/sample")
    /**
     description: feign service
     @param  name
     @return String string
     */
    String feignConsumer (@RequestParam (value = "name") String name);
}

在异常处理中,如果远程调用失败,直接返回,起到服务熔断作用。不会影响其他服务,避免出现系统 “雪崩”。

service/impl/FeignHystricServiceImpl.java

代码语言:javascript
复制
package com.feign.test.service.impl;
import com.feign.test.service.FeignService;
import org.springframework.stereotype.Component;
/**
 * @author gaiserchen
 * @date 2020.02.02
 * feign fallback
 */
@Component
public class FeignHystricServiceImpl implements FeignService {
    
    @Override
    public String feignConsumer (String name) {
        return "sorry," + name;
    }
}

Feign 启动结果

我们启动 Feign 程序之后,访问地址 <http://localhost:20202/feign-consumer?name=consumer>, 其返回结果如图,表示远程调用结果成功。

同时,feign 程序也需要注册到服务注册中心才能实现远程调用。我们可以查看服务注册中心的实例。

但当我们把之前启动的 eureka-client 服务停止时,再访问该地址,feign 会直接返回服务熔断的结果。

zuul 网关

zuul 是 spring cloud 的网关组件,起到路由代理转发的功能。同样构建一个 spring boot 工程,引入 zuul 组件依赖,其最终 maven 依赖如下:

zuul 依赖文件

代码语言:javascript
复制
<?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.eureka.test</groupId>
    <artifactId>zuulTest</artifactId>
    <version>1.0-SNAPSHOT</version>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.10.RELEASE</version>
    </parent>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.1.10.RELEASE</version>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-undertow</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
            <version>1.4.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zuul</artifactId>
            <version>1.4.7.RELEASE</version>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Greenwich.SR4</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

zuul 配置文件

zuul 网关主要起到请求代理和路由转发的作用,其转发规则就是在配置文件里配置,其配置如下,将所有 /eureka-client 下的请求转发到 eureka-client 这个服务,将所有 /service-feign 下的请求转发到 service-feign 这个服务。

代码语言:javascript
复制
# 服务名称
spring.application.name=eureka-zuul
# 服务端口号
server.port=20204
# 服务注册中心地址
eureka.client.serviceUrl.defaultZone=http://localhost:20200/eureka/
# zuul 网关代理规则
zuul.routes.eureka-client.path=/eureka-client/*
zuul.routes.eureka-client.serviceId=eureka-client
zuul.routes.service-feign.path=/service-feign/*
zuul.routes.service-feign.serviceId=service-feign

zuul 没有具体的接口和业务处理逻辑,所以只有 spring boot 启动代码

Application.java

代码语言:javascript
复制
package com.zuul.test;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
/**
 * @author gaiserchen
 * @date 2020.02.02
 * zuul client
 */
 
@EnableEurekaClient
@EnableZuulProxy
@SpringBootApplication
public class Application {
    public static void main (String [] args) {
        SpringApplication.run (Application.class, args);
    }
}

zuul 启动结果

zuul 启动之后,我们直接访问地址 <http://localhost:20204/eureka-client/sample?name=zuul>, 其结果如下,可以看到请求直接转发到了 eureka-client 服务。

我们接着访问 <http://localhost:20204/service-feign/feign-consumer?name=zuuConsumer>,可以看到,请求直接转发到了 service-feign 服务。

总结

以上就是几个 spring cloud 组件的基本入门,其中 config server 是配置中心,可以结合 gitlab 或者 git 仓库使用。而负载均衡器 Ribbon 已经集成在 Feign 远程调用组件里,当你的微服务在注册中心大于等于 2 个时,默认会开启轮询机制做负载均衡。当然,负载均衡策略也是可以配置的。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-02-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java后台 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
微服务引擎 TSE
微服务引擎(Tencent Cloud Service Engine)提供开箱即用的云上全场景微服务解决方案。支持开源增强的云原生注册配置中心(Zookeeper、Nacos 和 Apollo),北极星网格(腾讯自研并开源的 PolarisMesh)、云原生 API 网关(Kong)以及微服务应用托管的弹性微服务平台。微服务引擎完全兼容开源版本的使用方式,在功能、可用性和可运维性等多个方面进行增强。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档