为了账号安全,请及时绑定邮箱和手机立即绑定

SpringCloud项目开发入门教程

概述

本文将详细介绍SpringCloud项目开发入门,涵盖SpringCloud的基本概念、优势及应用场景,快速搭建第一个SpringCloud项目,并深入讲解服务注册与发现、服务间调用与负载均衡、服务容错与熔断、配置中心及服务网关等关键组件的使用。

引入SpringCloud
SpringCloud简介

Spring Cloud是由Pivotal团队提供的开源框架,它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发。Spring Cloud基于Spring Boot的自动化配置,利用Spring Boot的约定优于配置的理念,为分布式系统提供了一套微服务解决方案。Spring Cloud涵盖了分布式系统的多个方面,包括服务注册与发现、配置中心、服务网关、负载均衡、服务容错与熔断等。

Spring Cloud依赖于Netflix OSS等开源组件来实现各种分布式功能。Netflix OSS是Netflix公司发布的一系列开源组件,其中包括Eureka、Ribbon、Feign、Hystrix等,这些组件为Spring Cloud提供了强大的支撑。

SpringCloud的优势及应用场景

优势

  1. 分布式服务化:Spring Cloud可以快速构建分布式服务,简化服务间的通信。
  2. 服务治理:支持服务注册与发现,实现服务的动态治理。
  3. 负载均衡:通过Ribbon实现客户端的负载均衡。
  4. 服务容错:利用Hystrix实现服务的容错处理和熔断机制。
  5. 配置管理:通过Config组件实现配置的集中管理和动态刷新。
  6. API网关:通过Zuul实现API网关,提供统一的接口管理。
  7. 非功能服务:提供了断路器、日志监控、安全等非功能服务的支持。

应用场景

  • 微服务架构:构建微服务架构,实现服务的细粒度划分。
  • 云原生应用:支持云原生应用,实现服务的快速部署和弹性伸缩。
  • 多环境部署:支持多环境部署(开发、测试、生产等),实现配置的动态刷新。
  • 高可用性:支持服务的容错处理和负载均衡,提高系统的高可用性。
  • 统一入口:通过API网关实现服务的统一入口,提供统一接口管理和权限控制。
快速搭建第一个SpringCloud项目

准备工作

  1. 安装Java:确保已安装Java环境,并设置好JAVA_HOME环境变量。
  2. 安装Maven:确保已安装Maven,并设置好MAVEN_HOME环境变量。
  3. IDE配置:使用IDE(如IntelliJ IDEA或Eclipse)配置Maven。
  4. 新建Spring Boot项目:使用Spring Initializr或Maven创建一个新的Spring Boot项目。

搭建步骤

  1. 创建父工程(例如spring-cloud-parent):

    <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.example</groupId>
        <artifactId>spring-cloud-parent</artifactId>
        <version>1.0.0</version>
        <packaging>pom</packaging>
        <properties>
            <java.version>1.8</java.version>
            <spring-cloud.version>2021.0.0</spring-cloud.version>
        </properties>
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>${spring-cloud.version}</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
    </project>
  2. 创建子工程(服务提供者)(例如spring-cloud-provider):

    <parent>
        <groupId>com.example</groupId>
        <artifactId>spring-cloud-parent</artifactId>
        <version>1.0.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>spring-cloud-provider</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>
  3. 创建子工程(服务消费者)(例如spring-cloud-consumer):
    <parent>
        <groupId>com.example</groupId>
        <artifactId>spring-cloud-parent</artifactId>
        <version>1.0.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>spring-cloud-consumer</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
    </dependencies>

配置服务提供者

在服务提供者项目中,创建主类Application.java

package com.example.springcloudprovider;

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

@SpringBootApplication
@EnableEurekaClient
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

添加配置文件application.yml

server:
  port: 8081
spring:
  application:
    name: service-provider
eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:8761/eureka/

实现服务提供者:

package com.example.springcloudprovider;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ProviderController {
    @GetMapping("/hello")
    public String hello() {
        return "Hello from Service Provider";
    }
}

配置服务消费者

在服务消费者项目中,创建主类Application.java

package com.example.springcloudconsumer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableFeignClients
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

添加配置文件application.yml

server:
  port: 8082
spring:
  application:
    name: service-consumer
eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:8761/eureka/
ribbon:
  eureka:
    enabled: true

实现服务消费者:

package com.example.springcloudconsumer;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ConsumerController {
    @Autowired
    private ServiceProviderClient serviceProviderClient;

    @GetMapping("/consumer")
    public String consumer() {
        return serviceProviderClient.hello();
    }
}

定义Feign接口

package com.example.springcloudconsumer;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@FeignClient(name = "service-provider")
public interface ServiceProviderClient {
    @GetMapping("/hello")
    String hello();
}

启动Eureka服务注册中心

创建一个新的Spring Boot项目spring-cloud-eureka,在主类Application.java中启用Eureka服务:

package com.example.springcloudeureka;

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

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

添加配置文件application.yml

server:
  port: 8761
eureka:
  instance:
    hostname: localhost
  client:
    register-with-eureka: false
    fetch-registry: false
  server:
    enable-self-preservation: false

启动服务提供者和消费者

启动Eureka服务注册中心,访问http://localhost:8761,可以看到Eureka服务注册中心已启动。

启动服务提供者,访问http://localhost:8081,可以看到服务已注册到Eureka服务注册中心。

启动服务消费者,访问http://localhost:8082,可以看到服务消费者已注册到Eureka服务注册中心,并能成功调用服务提供者。

服务注册与发现
Eureka服务注册与发现原理

原理概述

Eureka是Netflix开源的一个基于REST的分布式服务治理组件,主要提供服务注册与发现的功能。Eureka Server作为服务注册中心,接收客户端的注册信息与心跳,保存服务实例的信息,并提供查询服务列表和健康状态的功能。Eureka Client作为服务消费者,向服务注册中心注册自身信息,并通过服务注册中心获取其他服务的实例信息,实现服务间的调用。

组件介绍

  1. Eureka Server

    • 服务注册中心,提供服务注册与发现的功能。
    • 收集客户端注册信息,保存服务实例的信息。
    • 提供查询服务列表和健康状态的功能。
    • 提供服务实例的心跳机制,监控服务实例的状态。
  2. Eureka Client
    • 服务提供者,向服务注册中心注册自身信息。
    • 服务消费者,从服务注册中心获取其他服务的实例信息,实现服务间的调用。

操作流程

  1. 服务提供者启动时向Eureka Server进行注册,每个实例定期通过心跳进行续约。
  2. 服务消费者启动时会向Eureka Server进行注册,同时会向Eureka Server获取服务实例列表。
  3. 服务注册中心接收服务提供者的注册信息,并保存服务实例的信息。
  4. 服务消费者通过服务注册中心获取服务实例列表,实现服务间的调用。

服务实例状态

  1. UP:服务实例正常运行。
  2. DOWN:服务实例停止运行。
  3. STARTING:服务实例正在启动。
  4. UNKNOWN:服务实例未知状态。
  5. CANCELED:服务实例被取消注册。

集群模式

Eureka Server可以配置为集群模式,支持多Eureka Server实例,通过集群模式保证服务注册中心的高可用性。

客户端配置

客户端可以通过配置文件application.yml进行配置,例如:

eureka:
  client:
  register-with-eureka: true
  fetch-registry: true
  service-url:
    defaultZone: http://localhost:8761/eureka/

快速搭建Eureka服务注册与发现

创建Eureka Server

创建一个新的Spring Boot项目spring-cloud-eureka,在主类Application.java中启用Eureka服务:

package com.example.springcloudeureka;

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

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

添加配置文件application.yml

server:
  port: 8761
eureka:
  instance:
    hostname: localhost
  client:
    register-with-eureka: false
    fetch-registry: false
  server:
    enable-self-preservation: false

启动Eureka Server

启动Eureka Server,访问http://localhost:8761,可以看到Eureka服务注册中心已启动。

实战Eureka服务注册与发现

创建服务提供者

创建一个新的Spring Boot项目spring-cloud-provider,在主类Application.java中启用Eureka服务:

package com.example.springcloudprovider;

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

@SpringBootApplication
@EnableEurekaClient
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

添加配置文件application.yml

server:
  port: 8081
spring:
  application:
    name: service-provider
eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:8761/eureka/

实现服务提供者:

package com.example.springcloudprovider;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ProviderController {
    @GetMapping("/hello")
    public String hello() {
        return "Hello from Service Provider";
    }
}

创建服务消费者

创建一个新的Spring Boot项目spring-cloud-consumer,在主类Application.java中启用Eureka服务:

package com.example.springcloudconsumer;

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

@SpringBootApplication
@EnableEurekaClient
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

添加配置文件application.yml

server:
  port: 8082
spring:
  application:
    name: service-consumer
eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:8761/eureka/
ribbon:
  eureka:
    enabled: true

实现服务消费者:

package com.example.springcloudconsumer;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ConsumerController {
    @Autowired
    private ServiceProviderClient serviceProviderClient;

    @GetMapping("/consumer")
    public String consumer() {
        return serviceProviderClient.hello();
    }
}

定义Feign接口

package com.example.springcloudconsumer;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@FeignClient(name = "service-provider")
public interface ServiceProviderClient {
    @GetMapping("/hello")
    String hello();
}

测试服务注册与发现

启动Eureka Server,启动服务提供者和服务消费者,访问http://localhost:8761,可以看到服务提供者和服务消费者已注册到Eureka服务注册中心。

访问服务消费者的地址,可以看到服务消费者已成功调用服务提供者。

服务间调用与负载均衡
Ribbon与Feign的使用

Ribbon简介

Ribbon是Netflix开源的一个客户端负载均衡器,它基于HTTP和TCP协议提供客户端的负载均衡。Ribbon内置了多种负载均衡策略,例如随机、轮询、最少活跃请求等,可以根据实际需求选择合适的策略。

Feign简介

Feign是Netflix开源的一个声明式Web服务客户端,它简化了HTTP请求的编写,提供了更优雅的接口定义方式。Feign内置了Ribbon的负载均衡能力,可以实现服务的负载均衡。

Ribbon与Feign的区别

  1. 代码编写风格

    • Ribbon需要手动编写HTTP请求代码,并通过负载均衡策略实现服务的调用。
    • Feign提供了更优雅的接口定义方式,通过注解实现服务的调用。
  2. 使用场景
    • Ribbon适用于需要自定义HTTP请求和负载均衡策略的场景。
    • Feign适用于需要声明式接口定义和内置负载均衡能力的场景。

Ribbon配置

基本配置

在服务提供者的application.yml中配置服务提供者:

server:
  port: 8081
spring:
  application:
    name: service-provider

在服务消费者的application.yml中配置服务消费者:

server:
  port: 8082
spring:
  application:
    name: service-consumer
eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:8761/eureka/
ribbon:
  eureka:
    enabled: true

服务调用

在服务消费者中通过RestTemplate实现服务调用:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class ConsumerController {
    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/consumer")
    public String consumer() {
        return restTemplate.getForObject("http://service-provider/hello", String.class);
    }
}

Feign配置

基本配置

添加Feign依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

在服务消费者的主类中启用Feign:

package com.example.springcloudconsumer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableFeignClients
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

在服务消费者中定义Feign接口:

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@FeignClient(name = "service-provider")
public interface ServiceProviderClient {
    @GetMapping("/hello")
    String hello();
}

在服务消费者中实现服务调用:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ConsumerController {
    @Autowired
    private ServiceProviderClient serviceProviderClient;

    @GetMapping("/consumer")
    public String consumer() {
        return serviceProviderClient.hello();
    }
}

实战服务调用与负载均衡

创建服务提供者

创建一个新的Spring Boot项目spring-cloud-provider,在主类Application.java中启用Eureka服务:

package com.example.springcloudprovider;

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

@SpringBootApplication
@EnableEurekaClient
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

添加配置文件application.yml

server:
  port: 8081
spring:
  application:
    name: service-provider

实现服务提供者:

package com.example.springcloudprovider;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ProviderController {
    @GetMapping("/hello")
    public String hello() {
        return "Hello from Service Provider";
    }
}

创建服务消费者

创建一个新的Spring Boot项目spring-cloud-consumer,在主类Application.java中启用Eureka服务和Feign:

package com.example.springcloudconsumer;

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

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

添加配置文件application.yml

server:
  port: 8082
spring:
  application:
    name: service-consumer
eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:8761/eureka/
ribbon:
  eureka:
    enabled: true

在服务消费者中定义Feign接口:

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@FeignClient(name = "service-provider")
public interface ServiceProviderClient {
    @GetMapping("/hello")
    String hello();
}

在服务消费者中实现服务调用:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ConsumerController {
    @Autowired
    private ServiceProviderClient serviceProviderClient;

    @GetMapping("/consumer")
    public String consumer() {
        return serviceProviderClient.hello();
    }
}

测试服务调用与负载均衡

启动Eureka Server,启动服务提供者和服务消费者,访问http://localhost:8082/consumer,可以看到服务消费者成功调用了服务提供者。

服务容错与熔断
Hystrix的工作原理

什么是Hystrix

Hystrix是Netflix开源的一个分布式系统的服务容错框架,它提供了断路器、隔离服务请求、缓存响应等机制,用于提高系统的容错性。

工作原理

Hystrix通过断路器机制实现服务的容错处理。断路器是一种状态机,有三种状态:

  1. 关闭:服务请求正常,断路器处于关闭状态。
  2. 打开:服务请求失败,断路器处于打开状态,拒绝服务请求。
  3. 半开:服务请求恢复,断路器处于半开状态,尝试服务请求。

当断路器处于打开状态时,服务请求会被拒绝,从而避免服务请求的失败雪崩效应。Hystrix还提供了隔离机制,将服务请求隔离到单独的线程池中执行,避免服务请求的阻塞。

断路器状态切换

断路器状态切换的逻辑如下:

  1. 关闭状态:服务请求正常,断路器处于关闭状态。
  2. 打开状态:当服务请求失败的比例超过阈值时,断路器会切换到打开状态,拒绝服务请求。
  3. 半开状态:当服务请求恢复正常时,断路器会切换到半开状态,尝试服务请求。
  4. 关闭状态:当服务请求成功时,断路器会切换到关闭状态。

配置参数

Hystrix提供了多种配置参数,例如:

  • 命令超时:设置命令超时时间。
  • 失败阈值:设置失败阈值,超过阈值时断路器切换到打开状态。
  • 恢复阈值:设置恢复阈值,超过阈值时断路器切换到半开状态。
  • 隔离策略:设置隔离策略,例如隔离到单独的线程池中。

实战服务容错与熔断机制

创建服务提供者

创建一个新的Spring Boot项目spring-cloud-provider,在主类Application.java中启用Eureka服务:

package com.example.springcloudprovider;

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

@SpringBootApplication
@EnableEurekaClient
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

添加配置文件application.yml

server:
  port: 8081
spring:
  application:
    name: service-provider

实现服务提供者:

package com.example.springcloudprovider;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ProviderController {
    @GetMapping("/hello")
    public String hello() {
        return "Hello from Service Provider";
    }
}

创建服务消费者

创建一个新的Spring Boot项目spring-cloud-consumer,在主类Application.java中启用Eureka服务和Feign:

package com.example.springcloudconsumer;

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

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

添加配置文件application.yml

server:
  port: 8082
spring:
  application:
    name: service-consumer
eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:8761/eureka/
ribbon:
  eureka:
    enabled: true

定义Feign接口:

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@FeignClient(name = "service-provider")
public interface ServiceProviderClient {
    @GetMapping("/hello")
    String hello();
}

在服务消费者中实现服务调用:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ConsumerController {
    @Autowired
    private ServiceProviderClient serviceProviderClient;

    @GetMapping("/consumer")
    public String consumer() {
        return serviceProviderClient.hello();
    }
}

添加Hystrix熔断机制

在服务消费者中添加Hystrix熔断机制:

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@FeignClient(name = "service-provider", fallback = ServiceProviderFallback.class)
public interface ServiceProviderClient {
    @GetMapping("/hello")
    String hello();
}

定义熔断类:

import org.springframework.stereotype.Component;

@Component
public class ServiceProviderFallback implements ServiceProviderClient {
    @Override
    public String hello() {
        return "Fallback: Service Provider is unavailable";
    }
}

测试服务容错与熔断机制

启动Eureka Server,启动服务提供者和服务消费者,访问http://localhost:8082/consumer,可以看到服务消费者成功调用了服务提供者。

停止服务提供者,访问http://localhost:8082/consumer,可以看到服务消费者返回熔断类的错误信息。

配置中心
Config配置中心的使用

Config简介

Spring Cloud Config是Spring Cloud提供的一套配置管理工具,支持对配置文件进行集中管理和动态刷新。Spring Cloud Config主要包括Config Server和Config Client两部分,Config Server作为配置中心,提供配置文件的访问接口;Config Client作为客户端,从Config Server获取配置文件。

配置中心架构

  1. Config Server

    • 配置中心,提供配置文件的访问接口。
    • 支持多种存储方式,例如本地文件、Git、SVN等。
    • 支持配置文件的版本控制和动态刷新。
  2. Config Client
    • 客户端,从Config Server获取配置文件。
    • 支持配置文件的多环境部署,例如开发、测试、生产等。
    • 支持配置文件的动态刷新。

配置中心使用步骤

  1. 创建Config Server
    • 通过Spring Boot创建一个新的项目spring-cloud-config-server
    • 添加依赖spring-cloud-starter-config
    • 配置文件bootstrap.yml中指定配置文件的存储方式,例如本地文件、Git等。
    • 启动Config Server,提供配置文件的访问接口。
  2. 创建Config Client
    • 通过Spring Boot创建一个新的项目spring-cloud-config-client
    • 添加依赖spring-cloud-starter-config
    • 配置文件bootstrap.yml中指定Config Server的地址。
    • 启动Config Client,从Config Server获取配置文件。

实战动态刷新配置功能

创建Config Server

创建一个新的Spring Boot项目spring-cloud-config-server,在主类Application.java中启用Config Server:

package com.example.springcloudconfigserver;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;

@SpringBootApplication
@EnableConfigServer
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

添加配置文件bootstrap.yml

spring:
  application:
    name: config-server
cloud:
  config:
    server:
      git:
        uri: https://github.com/example/config-repo
        username: your-username
        password: your-password

创建Config Client

创建一个新的Spring Boot项目spring-cloud-config-client,在主类Application.java中启用Config Client:

package com.example.springcloudconfigclient;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

添加配置文件bootstrap.yml

spring:
  application:
    name: service-client
cloud:
  config:
    server:
      uri: http://localhost:8888

实现动态刷新配置功能

在Config Client中实现动态刷新配置功能:

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RefreshScope
public class ConfigController {
    @Value("${spring.application.name}")
    private String appName;

    @GetMapping("/config")
    public String getConfig() {
        return "Current App Name: " + appName;
    }
}

测试动态刷新配置功能

启动Config Server,启动Config Client,访问http://localhost:8080/config,可以看到Config Client获取到Config Server的配置文件。

修改Config Server的配置文件,刷新Config Client的配置,访问http://localhost:8080/config,可以看到Config Client获取到最新的配置文件。

服务网关
Zuul网关介绍

Zuul简介

Zuul是Netflix开源的一个API网关,主要用于提供动态路由、服务代理、数据过滤等功能。Zuul提供了多种过滤器,可以实现请求路由、请求过滤、请求转发等功能。

网关架构

  1. 路由过滤器

    • 路由过滤器用于实现路由功能,将请求路由到对应的服务实例。
    • 路由过滤器可以通过路径匹配、请求头匹配等方式实现路由规则。
  2. 预处理过滤器

    • 预处理过滤器用于实现请求的预处理功能,例如身份验证、请求日志等。
    • 预处理过滤器可以在请求到达服务实例之前执行。
  3. 后处理过滤器
    • 后处理过滤器用于实现请求的后处理功能,例如响应日志、响应缓存等。
    • 后处理过滤器可以在请求到达服务实例之后执行。

网关使用步骤

  1. 创建Zuul网关
    • 通过Spring Boot创建一个新的项目spring-cloud-zuul-gateway
    • 添加依赖spring-cloud-starter-zuul
    • 配置文件application.yml中指定路由规则。
    • 启动Zuul网关,实现服务的统一入口。
  2. 创建服务提供者和消费者
    • 创建服务提供者和消费者,实现服务的提供和消费。
    • 通过Zuul网关调用服务提供者和服务消费者。

Zuul过滤器

路由过滤器

路由过滤器可以通过路径匹配、请求头匹配等方式实现路由规则。例如:

zuul:
  routes:
  service-provider:
    path: /service-provider/**
    serviceId: service-provider
  service-consumer:
    path: /service-consumer/**
    serviceId: service-consumer

前置过滤器

前置过滤器可以在请求到达服务实例之前执行。例如:

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.springframework.stereotype.Component;

@Component
public class PreFilter extends ZuulFilter {
    @Override
    public String filterType() {
        return "pre";
    }

    @Override
    public int filterOrder() {
        return 0;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        ctx.addZuulResponseHeader("X-Filter-Pre", "PreFilter");
        return null;
    }
}

后置过滤器

后置过滤器可以在请求到达服务实例之后执行。例如:

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.springframework.stereotype.Component;

@Component
public class PostFilter extends ZuulFilter {
    @Override
    public String filterType() {
        return "post";
    }

    @Override
    public int filterOrder() {
        return 0;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        ctx.addZuulResponseHeader("X-Filter-Post", "PostFilter");
        return null;
    }
}

实战API网关的创建与使用

创建Zuul网关

创建一个新的Spring Boot项目spring-cloud-zuul-gateway,在主类Application.java中启用Zuul网关:

package com.example.springcloudzuulgateway;

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;

@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

添加配置文件application.yml

server:
  port: 8080
spring:
  application:
    name: zuul-gateway
eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:8761/eureka/
zuul:
  routes:
    service-provider:
      path: /service-provider/**
      serviceId: service-provider
    service-consumer:
      path: /service-consumer/**
      serviceId: service-consumer

创建服务提供者和消费者

创建服务提供者和消费者,实现服务的提供和消费。配置文件application.yml中指定服务名:

spring:
  application:
    name: service-provider

实现服务提供者:

package com.example.springcloudprovider;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ProviderController {
    @GetMapping("/hello")
    public String hello() {
        return "Hello from Service Provider";
    }
}

实现服务消费者:

package com.example.springcloudconsumer;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@FeignClient(name = "service-provider")
public interface ServiceProviderClient {
    @GetMapping("/hello")
    String hello();
}

@RestController
public class ConsumerController {
    @Autowired
    private ServiceProviderClient serviceProviderClient;

    @GetMapping("/consumer")
    public String consumer() {
        return serviceProviderClient.hello();
    }
}

测试API网关的创建与使用

启动Eureka Server,启动服务提供者和服务消费者,启动Zuul网关,访问http://localhost:8080/service-provider/hello,可以看到服务提供者成功提供服务。

访问http://localhost:8080/service-consumer/consumer,可以看到服务消费者成功调用服务提供者。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消