记录Spring-Cloud-Netflix搭建过程

1,795 阅读3分钟

概述

为了更好的学习理解springCloud的搭建过程,在此单纯记录一下搭建过程便于理解以及日后回顾。

项目架构

  • 1、统一依赖管理:Spring Cloud Finchley.RC1
  • 2、服务治理注册与发现:Spring Cloud Netflix Eureka
  • 3、声明式服务调用(服务消费者):Spring Cloud OpenFeign
  • 4、服务容错保护限流降级(熔断器):Spring Cloud Netflix Hystrix
  • 5、分布式链路追踪(链路器):Spring Cloud Zipkin
  • 6、网关路由代理调用(统一网关):Spring Cloud Gateway
  • 7、分布式统一配置中心(配置中心):Spring Cloud Config
  • 8、服务监控:Spring Boot Amdin

1、Spring Cloud Finchley 创建统一依赖管理

Finchley :统一版本管理套件方便对jar 的版本进行管理

1、创建文件夹spring-cloud-dependencies

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>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.2.RELEASE</version>
    </parent>

    <groupId>com.fjhckj</groupId>
    <artifactId>spring-cloud-dependencies</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <name>spring-cloud-dependencies</name>
    <inceptionYear>2018-Now</inceptionYear>

    <properties>
        <!-- Environment Settings -->
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

        <!-- Spring Settings -->
        <spring-cloud.version>Finchley.RC1</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>

    <build>
        <plugins>
            <!-- Compiler 插件, 设定 JDK 版本 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <showWarnings>true</showWarnings>
                </configuration>
            </plugin>

            <!-- 打包 jar 文件时,配置 manifest 文件,加入 lib 包的 jar 依赖 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <archive>
                        <addMavenDescriptor>false</addMavenDescriptor>
                    </archive>
                </configuration>
                <executions>
                    <execution>
                        <configuration>
                            <archive>
                                <manifest>
                                    <!-- Add directory entries -->
                                    <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
                                    <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
                                    <addClasspath>true</addClasspath>
                                </manifest>
                            </archive>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

            <!-- resource -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
            </plugin>

            <!-- install -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-install-plugin</artifactId>
            </plugin>

            <!-- clean -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-clean-plugin</artifactId>
            </plugin>

            <!-- ant -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-antrun-plugin</artifactId>
            </plugin>

            <!-- dependency -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
            </plugin>
        </plugins>

        <pluginManagement>
            <plugins>
                <!-- Java Document Generate -->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-javadoc-plugin</artifactId>
                    <executions>
                        <execution>
                            <phase>prepare-package</phase>
                            <goals>
                                <goal>jar</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>

                <!-- YUI Compressor (CSS/JS压缩) -->
                <plugin>
                    <groupId>net.alchim31.maven</groupId>
                    <artifactId>yuicompressor-maven-plugin</artifactId>
                    <version>1.5.1</version>
                    <executions>
                        <execution>
                            <phase>prepare-package</phase>
                            <goals>
                                <goal>compress</goal>
                            </goals>
                        </execution>
                    </executions>
                    <configuration>
                        <encoding>UTF-8</encoding>
                        <jswarn>false</jswarn>
                        <nosuffix>true</nosuffix>
                        <linebreakpos>30000</linebreakpos>
                        <force>true</force>
                        <includes>
                            <include>**/*.js</include>
                            <include>**/*.css</include>
                        </includes>
                        <excludes>
                            <exclude>**/*.min.js</exclude>
                            <exclude>**/*.min.css</exclude>
                        </excludes>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>

        <!-- 资源文件配置 -->
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <excludes>
                    <exclude>**/*.java</exclude>
                </excludes>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
            </resource>
        </resources>
    </build>

    <repositories>
        <repository>
            <id>aliyun-repos</id>
            <name>Aliyun Repository</name>
            <url>http://maven.aliyun.com/nexus/content/groups/public</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>

        <repository>
            <id>sonatype-repos</id>
            <name>Sonatype Repository</name>
            <url>https://oss.sonatype.org/content/groups/public</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>sonatype-repos-s</id>
            <name>Sonatype Repository</name>
            <url>https://oss.sonatype.org/content/repositories/snapshots</url>
            <releases>
                <enabled>false</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>

        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

    <pluginRepositories>
        <pluginRepository>
            <id>aliyun-repos</id>
            <name>Aliyun Repository</name>
            <url>http://maven.aliyun.com/nexus/content/groups/public</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>
</project>

3、托管pom 下载maven

2、Spring Cloud Netflix Eureka 服务治理注册与发现

eureka:分布式架构中多服务之间接口互相调用,需要记录各个服务之间的ip端口等信息,使用eureka 后可以将ip端口等交由eureka托管,服务之间访问时只需要通过服务名称进行调用即可。

1、创建服务注册中心

1、创建基础spring-boot项目

2、增加eureka依赖

     <!-- Spring Cloud Eureka Begin -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    <!-- Spring Cloud Eureka end -->

3、继承pom至统一依赖管理

    <parent>
        <groupId>com.fjhckj</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>1.0.0-SNAPSHOT</version>
        <relativePath>../spring-cloud-dependencies/pom.xml</relativePath>
    </parent>

完整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>

    <parent>
        <groupId>com.fjhckj</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>1.0.0-SNAPSHOT</version>
        <relativePath>../spring-cloud-dependencies/pom.xml</relativePath>
    </parent>

    <artifactId>spring-cloud-eureka</artifactId>
    <name>spring-cloud-eureka</name>
    <packaging>jar</packaging>



    <dependencies>
        <!-- Spring Boot Begin -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        <!-- Spring Boot End -->

        <!-- Spring Cloud Begin -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
        <!-- Spring Cloud End -->
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <mainClass>com.fjhckj.springcloudeureka.SpringCloudEurekaApplication</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

3、在Application中增加注解@EnableEurekaServer

4、配置文件设置

#服务名称
spring:
  application:
    name: spring-cloud-eureka
#服务端口
server:
  port: 8081

#eureka.client.registerWithEureka:false
#eureka.client.fetchRegistry:false
#表明是eureka服务端
#eureka.client.serviceUrl.defaultZone 网关注册地址
eureka:
  instance:
    hostname: localhost
  client:
    registerWithEureka: false
    fetchRegistry: false
    serviceUrl:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

5、启动eureka测试eureka网关是否能进入

3、声明式服务调用:Spring Cloud OpenFeign(服务消费者)

feign:各个服务之间的调用的封装,使调用其他服务的代码更加优雅。feign 集成了 中集成了ribbon 方式调用其他服务接口,还集成了 hystrix 熔断器

1、创建服务提供者

1、创建基础springboot项目
2、继承pom至统一依赖管理
3、增加eureka依赖
    <!-- Spring Cloud Begin -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    <!-- Spring Cloud End -->
4、完整pom如下
<?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>
    <parent>
        <groupId>com.fjhckj</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>1.0.0-SNAPSHOT</version>
        <relativePath>../spring-cloud-dependencies/pom.xml</relativePath>
    </parent>

    <artifactId>spring-cloud-service</artifactId>
    <packaging>jar</packaging>

    <name>spring-cloud-service</name>

    <properties>
        <java.version>1.8</java.version>
    </properties>

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

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

        <!-- Spring Cloud Begin -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
        <!-- Spring Cloud End -->
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <mainClass>com.fjhckj.springcloudservice.SpringCloudServiceApplication</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
5、设置配置文件
#spring.application.name 服务名称
spring:
  application:
    name: spring-cloud-service
#server.port 端口
server:
  port: 8082
# eureka.client.serviceUrl.defaultZone eureka网关注册地址
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8081/eureka/

6、增加eureka客户端注解

@EnableEurekaClient

7、创建restfull接口供消费者使用

8、启动提供者

9、通过eureka提供的服务地址访问接口

2、创建服务消费者通过feign方式调用提供者接口

1、创建基础spring-boot项目
2、继承pom至统一依赖管理
3、增加pom依赖内容如下
     <!--feign Begin-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
     <!--feign End-->
4、完整pom如下
<?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>
    <parent>
        <groupId>com.fjhckj</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>1.0.0-SNAPSHOT</version>
        <relativePath>../spring-cloud-dependencies/pom.xml</relativePath>
    </parent>

    <artifactId>spring-cloud-feign</artifactId>
    <name>spring-cloud-feign</name>
    <packaging>jar</packaging>

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

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

        <!--feign Begin-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!--feign End-->
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <mainClass>com.fjhckj.springcloudfeign.SpringCloudFeignApplication</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>
5、修改配置文件
spring:
  application:
    name: spring-cloud-feign

server:
  port: 8083

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8081/eureka/

#解决使用feign访问服务提供者时找不到提供者的问题
ribbon:
  eureka:
    enabled: true
6、增加注解@EnableEurekaClient eureka客户端注解、@EnableFeignClients feign注解

7、创建消费接口调用提供者接口
1、创建FeignSerivice接口

增加@FeignClient(value = "spring-cloud-service") 注解 value 为服务网关eureka网关注册的Application名称

增加抽象方法

String helloWorld(@RequestParam("message") String message);
ps:注意增加@RequestParam否则参数会报错

抽象方法上增加@RequestMapping(value = "spring-cloud-service/hello-world", method = RequestMethod.GET) 对应提供者的接口地址

2、创建提供者rest接口调用service的方法

8、启动消费者测试接口情况

9、Feign 自动实现负载均衡测试
1、提供者中输出端口号
2、开启两个提供者提供服务 端口号分别为8082:8084

3、测试结果-1

4、测试结果-2

10、Feign 中集成了ribbon 顺道测试一下

ps:其中有坑在使用ribbon时注意服务名称是要与配置文件中的spring.application.name 一致 使用Feign时则可以使用eureka 网关上的application 名称

4、服务容错保护限流降级:Spring Cloud Netflix Hystrix(熔断器)

为了保证其高可用,单个服务通常会集群部署。由于网络原因或者自身的原因,服务并不能保证 100% 可用,。当对特定的服务的调用的不可用达到一个阀值时将触发熔断返回fallback的方法实现值。

1、feign 中使用熔断器

1、配置文件中开启hystrix
#开启feign 支持熔断器
feign:
  hystrix:
    enabled: true
2、创建FeignServiceImp 实现类 实现 FeignService 并交由spring托管

3、FeignService @FeignClient 注解 增加fallback = FeignServiceImp.class

4、测试熔断器
1、服务提供者状态正常下结果

2、关闭提供者后测试结果

5、断点后无意间看到熔断反射的堆栈信息顺道做个记录

2、熔断监控

1、feign 项目增加依赖
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
2、开启注解支持@EnableHystrixDashboard

3、关闭spring-cloud-service 触发feign 熔断并进入HystrixDashboard监控页面查看结果

http://127.0.0.1:8083/hystrix

5、分布式链路追踪(链路器):Spring Cloud Zipkin

随着服务的越来越多,对调用链的分析会越来越复杂服务的调用关系可能是这样

为了更清晰的管理服务之间的调用关系使用链路追踪

1、创建基础boot

2、继承统一管理pom

3、增加zipkin依赖

     <dependency>
            <groupId>io.zipkin.java</groupId>
            <artifactId>zipkin-server</artifactId>
            <version>${zipkin.version}</version>
        </dependency>
        <dependency>
            <groupId>io.zipkin.java</groupId>
            <artifactId>zipkin-autoconfigure-ui</artifactId>
            <version>${zipkin.version}</version>
        </dependency>

版本为2.12.0

完整pom
<?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>
    <parent>
        <groupId>com.fjhckj</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>1.0.0-SNAPSHOT</version>
        <relativePath>../spring-cloud-dependencies/pom.xml</relativePath>
    </parent>

    <artifactId>spring-cloud-zipkin</artifactId>
    <packaging>jar</packaging>

    <name>spring-cloud-zipkin</name>


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

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

        <dependency>
            <groupId>io.zipkin.java</groupId>
            <artifactId>zipkin-server</artifactId>
            <version>${zipkin.version}</version>
        </dependency>
        <dependency>
            <groupId>io.zipkin.java</groupId>
            <artifactId>zipkin-autoconfigure-ui</artifactId>
            <version>${zipkin.version}</version>
        </dependency>

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

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <mainClass>com.fjhckj.springcloudzipkin.SpringCloudZipkinApplication</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

4、修改配置文件

spring:
  application:
    name: spring-cloud-zipkin


server:
  port: 8084

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8081/eureka/

management:
  metrics:
    web:
      server:
        auto-time-requests: false

5、开启注解支持@EnableZipkinServer

6、除zipkin与统一管理 以外所有的模块需要被zipkin 监控

pom中增加

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

配置文件增加

spring:
  zipkin:
    base-url: http://localhost:8084

7、测试zipkin 追踪服务链路

6、网关路由代理调用(统一网关):Spring Cloud Gateway

由于服务过多对外暴露的接口可能也有很多,为了统一管控使用统一网关进行代理,这样只需向外暴露一个端口,根据不同的服务名网关进行对应服务的调用。

1、gateway实现简单路由

1、创建spring-boot

2、继承统一管理pom

3、增加依赖

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

4、完整依赖

<?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>
    <parent>
        <groupId>com.fjhckj</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>1.0.0-SNAPSHOT</version>
        <relativePath>../spring-cloud-dependencies/pom.xml</relativePath>
    </parent>

    <artifactId>spring-cloud-gateway</artifactId>
    <packaging>jar</packaging>

    <name>spring-cloud-gateway</name>


    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</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-gateway</artifactId>
        </dependency>

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

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

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <mainClass>com.fjhckj.springcloudgateway.SpringCloudGatewayApplication</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

5、修改配置文件

spring:
  application:
    #服务名称
    name: SPRING-CLOUD-GATEWAY
  zipkin:
    #zipkin服务地址
    base-url: http://localhost:8084
  cloud:
    gateway:
      discovery:
        locator:
          #开启支持eureka以服务名形式调用
          enabled: true
      routes:
          # 自定义服务名称:ps:特殊名称拥有特殊作用如after_route、before_route、between_route
        - id: SPRING-CLOUD-FEIGN
          #lb:以LoadBalancerClient形式调用请求 SPRING-CLOUD-FEIGN eureka上注册的服务名
          uri: lb://SPRING-CLOUD-FEIGN
          predicates:
            #匹配get post 请求
            - Method=GET,POST
        - id: SPRING-CLOUD-SERVICE
          uri: lb://SPRING-CLOUD-SERVICE
          predicates:
            - Method=GET,POST
server:
  port: 8085

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8081/eureka/  # eureka 服务注册地址

![](https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2019/5/18/16ac6e5dd1c1960d~tplv-t2oaga2asx-image.image)

6、启动gateway 网关由网关统一访问 feign 与 service 两个服务

1、网关访问feign 情况

2、网关访问service 情况

7、遇到的坑

1、gateway spring-boot-starter-webflux 与 spring-boot-starter-tomcat jar包冲突,删除下图jar包

ps:每次刷新都会出来这几个jar

解决方案: Ctrl + shift + Alt + U 找到类依赖关系pom 中排除

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-tomcat</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
3、网关调用时要按照eureka上注册的名称而是不yml 中配置的名称为了统一将所有的yml 中配置的服务名称全部大写

2、gateway 实现简单全局过滤功能

package com.fjhckj.springcloudgateway.filter;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.HashMap;
import java.util.Map;

/**
 * 自定义全局过滤器
 */
@Component
public class MyGlobalFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //获取参数
        String token =  exchange.getRequest().getQueryParams().getFirst("token");
        if (StringUtils.isBlank(token)) {
            ServerHttpResponse response = exchange.getResponse();
            Map<String,Object> resuMap = new HashMap<>();
            resuMap.put("status", -1);
            resuMap.put("massage", "鉴权失败");
            //转化为json 并转为字节数组
            ObjectMapper objectMapper = new ObjectMapper();
            byte[] data = new byte[0];
            try {
                data = objectMapper.writeValueAsBytes(resuMap);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            // 输出错误信息到页面
            DataBuffer buffer = response.bufferFactory().wrap(data);
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
            return response.writeWith(Mono.just(buffer));
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        //filter执行的优先级,值越小则优先级越大
        return 0;
    }
}

gateway 更多自定义过滤方式 gateway 更多自定义过滤方式

3、gateway 实现全局熔断

1、增加依赖
    <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>
2、完整配置文件
spring:
  application:
    #服务名称
    name: SPRING-CLOUD-GATEWAY
  zipkin:
    #zipkin服务地址
    base-url: http://localhost:8084
  cloud:
    gateway:
      discovery:
        locator:
          #开启支持eureka以服务名形式调用
          enabled: true
      routes:
          # 自定义服务名称:ps:特殊名称拥有特殊作用如after_route、before_route、between_route
        - id: SPRING-CLOUD-FEIGN
          #lb:以LoadBalancerClient形式调用请求 SPRING-CLOUD-FEIGN eureka上注册的服务名
          uri: lb://SPRING-CLOUD-FEIGN
          predicates:
            #匹配get post 请求
            - Method=GET,POST

        - id: SPRING-CLOUD-SERVICE
          uri: lb://SPRING-CLOUD-SERVICE
          predicates:
            - Method=GET,POST
      #全局熔断服务为响应或响应超时触发熔断
      default-filters:
        - name: Hystrix
          args:
            name: fallbackcmd
            fallbackUri: forward:/defaultfallback


# hystrix 信号量隔离,3秒后自动超时
hystrix:
  command:
    default:
      execution:
        isolation:
          strategy: SEMAPHORE
          thread:
            timeoutInMilliseconds: 3000
  shareSecurityContext: true



server:
  port: 8085

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8081/eureka/  # eureka 服务注册地址

主要增加

3、熔断回调接口
package com.fjhckj.springcloudgateway.controller;

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

import java.util.HashMap;
import java.util.Map;

/**
 * 默认熔断处理
 */
@RestController
public class DefaultHystrixController {

    @RequestMapping("/defaultfallback")
    public Map<String,String> defaultfallback(){
        Map<String,String> map = new HashMap<>();
        map.put("resultCode","error");
        map.put("resultMessage","网络连接超时");
        map.put("resultObj","null");
        return map;
    }
}

4、测试熔断

7、分布式统一配置中心(配置中心):Spring Cloud Config

Spring Cloud Config:在分布式系统中,由于服务数量巨多,为了方便服务配置文件的统一管理,实时更新而产生的组件。

1、服务端

1、基础项目继承pom

2、pom 增加

<dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-config-server</artifactId>
</dependency>

3、完整pom

<?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>
    <parent>
        <groupId>com.fjhckj</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>1.0.0-SNAPSHOT</version>
        <relativePath>../spring-cloud-dependencies/pom.xml</relativePath>
    </parent>

    <artifactId>spring-cloud-config</artifactId>
    <packaging>jar</packaging>

    <name>spring-cloud-config</name>

    <dependencies>
        <!-- Spring Boot Begin -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- Spring Boot End -->

        <!-- Spring Cloud Begin -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
        <!-- Spring Cloud End -->
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

4、配置文件

spring:
  application:
    #服务名
    name: SPRING-CLOUD-CONFIG
  cloud:
    config:
      #仓库分支
      label: master
      server:
        git:
          # git 地址
          uri: xxx
          # 文件夹
          search-paths: xxx
          # git 账户
          username: xxx
          # git 密码
          password: xxx
          # 云配置拉取的缓存路径
          basedir: xxx



server:
  port: 8888

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8081/eureka/

5、启动类增加注解@EnableConfigServer

6、测试文件访问

文件映射支持如下几种方式

http://ip:port/{application}/{profile}[/{label}]
http://ip:port/{application}-{profile}.yml
http://ip:port/{label}/{application}-{profile}.yml
http://ip:port/{application}-{profile}.properties
http://ip:port/{label}/{application}-{profile}.properties

2、客户端

1、增加pom

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

2、由于使用云配置所以配置文件修改如下

spring:
  cloud:
    config:
      uri: http://localhost:8888
      name: serviceApplication
      label: master
      profile: dev

3、测试客户端获取云配置

仓库下拥有配置文件如下

两个文件serviceApplication-dev与serviceApplication-test端口分别为8082:9082

3、遇到的坑 yml 中定义的数组形式参数被转换为

spring.cloud.gateway.routes[0].id=SPRING-CLOUD-FEIGN 之后在客户端中获取改文件时报错

Could not locate PropertySource: Error while extracting response for type [class org.springframework.cloud.config.environment.Environment] and content type [application/xml;charset=UTF-8]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Unexpected character '[' (code 91) excepted space, or '>' or "/>"
 at [row,col {unknown-source}]: [1,593]; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Unexpected character '[' (code 91) excepted space, or '>' or "/>"

解决方法未知

断点跟踪至

解析下一个属性名时抛出异常

8、服务监控:Spring Boot Amdin

随着服务越来越多对于各个微服务系统的健康状态、会话数量、并发数、服务资源、延迟等度量信息的收集就成为了一个挑战,spring boot admin 为此而生。

1、服务端

1、基础项目继承pom

2、增加pom

${spring-cloud-admin.version} 为 2.0.0

    <dependency>
            <groupId>org.jolokia</groupId>
            <artifactId>jolokia-core</artifactId>
        </dependency>

        <dependency>
            <groupId>de.codecentric</groupId>
            <artifactId>spring-boot-admin-starter-server</artifactId>
            <version>${spring-cloud-admin.version}</version>
    </dependency>

3、完整pom

<?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>
    <parent>
        <groupId>com.fjhckj</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>1.0.0-SNAPSHOT</version>
        <relativePath>../spring-cloud-dependencies/pom.xml</relativePath>
    </parent>

    <artifactId>spring-cloud-admin</artifactId>
    <packaging>jar</packaging>

    <name>spring-cloud-admin</name>


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

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

        <dependency>
            <groupId>org.jolokia</groupId>
            <artifactId>jolokia-core</artifactId>
        </dependency>

        <dependency>
            <groupId>de.codecentric</groupId>
            <artifactId>spring-boot-admin-starter-server</artifactId>
            <version>${spring-cloud-admin.version}</version>
        </dependency>

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

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

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

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

4、配置文件

spring:
  application:
    name: SPRING-CLOUD-ADMIN
  zipkin:
    base-url: http://localhost:8084

server:
  port: 8087

management:
  endpoint:
    health:
      show-details: always
  endpoints:
    web:
      exposure:
        include: health,info

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8081/eureka/

2、客户端

1、增加pom

    <dependency>
            <groupId>org.jolokia</groupId>
            <artifactId>jolokia-core</artifactId>
        </dependency>
        <dependency>
            <groupId>de.codecentric</groupId>
            <artifactId>spring-boot-admin-starter-client</artifactId>
            <version>${spring-cloud-admin.version}</version>
    </dependency>

2、增加配置文件

spring:
    boot:
        admin:
          client:
            # spring-clouda-dmin 监控地址
            url: http://localhost:8087

3、开启所有服务测试监控效果

除admin 本身外所有服务均上线

本篇完结

1、该篇总结

整套系统的搭建大概耗时一周,当然只有晚上几个小时的时间,基本上搭建的时间都在集成gateway 网关上与config 配置中心上了,学习过程中又出现很多新名例如 :响应式编程、netty 等,越学感觉不会的越多.... 搭建过程中也遇到各种奇葩问题什么大小写名称啦,特殊字符啦七七八八的,不过好在系统最终还是搭起来了....

2、参考了太多的博客这边就不列了偷个懒