SpringBoot2.2.2+SpringCloud-Hoxton.SR1整合eureka/gateway

1.最近在学习SpringCloud分布式项目的知识,所以打算把自己学习到的知识也记录下来,为什么选择学习SpringCloud呢?因为分布式框架还有dubbo,如下图应该可以成为我为什么想学习SpringCloud而不是dubbo了。

那Dubbo和SpringCloud有什么区别呢?如下图给出了标准答案:

 

2.好了,上面的区别我们看到了,那么接下来就是想办法将SpringBoot和SpringCloud整合了,在整合之前有个问题要注意,就是SpringBoot版本的不同也需要整合不同的SpringCloud版本,下面官方网址查看对应的版本:https://start.spring.io/actuator/info,或者:https://blog.csdn.net/ZFD0510/article/details/92839001

"spring-cloud": {
      "Finchley.M2": "Spring Boot >=2.0.0.M3 and <2.0.0.M5",
      "Finchley.M3": "Spring Boot >=2.0.0.M5 and <=2.0.0.M5",
      "Finchley.M4": "Spring Boot >=2.0.0.M6 and <=2.0.0.M6",
      "Finchley.M5": "Spring Boot >=2.0.0.M7 and <=2.0.0.M7",
      "Finchley.M6": "Spring Boot >=2.0.0.RC1 and <=2.0.0.RC1",
      "Finchley.M7": "Spring Boot >=2.0.0.RC2 and <=2.0.0.RC2",
      "Finchley.M9": "Spring Boot >=2.0.0.RELEASE and <=2.0.0.RELEASE",
      "Finchley.RC1": "Spring Boot >=2.0.1.RELEASE and <2.0.2.RELEASE",
      "Finchley.RC2": "Spring Boot >=2.0.2.RELEASE and <2.0.3.RELEASE",
      "Finchley.SR4": "Spring Boot >=2.0.3.RELEASE and <2.0.999.BUILD-SNAPSHOT",
      "Finchley.BUILD-SNAPSHOT": "Spring Boot >=2.0.999.BUILD-SNAPSHOT and <2.1.0.M3",
      "Greenwich.M1": "Spring Boot >=2.1.0.M3 and <2.1.0.RELEASE",
      "Greenwich.SR4": "Spring Boot >=2.1.0.RELEASE and <2.1.12.BUILD-SNAPSHOT",
      "Greenwich.BUILD-SNAPSHOT": "Spring Boot >=2.1.12.BUILD-SNAPSHOT and <2.2.0.M4",
      "Hoxton.SR1": "Spring Boot >=2.2.0.M4 and <2.2.3.BUILD-SNAPSHOT",
      "Hoxton.BUILD-SNAPSHOT": "Spring Boot >=2.2.3.BUILD-SNAPSHOT"
    }

 

 

3.下面创建一个dafu-spring-cloud父项目,pom文件为:

  <!--父模块名称-->
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example.dafu</groupId>
    <artifactId>springcloud</artifactId>
    <version>1.0-SNAPSHOT</version>
    <name>maven-springcloud</name>
    <!--全局版本管理-->
    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-cloud.version>Hoxton.SR1</spring-cloud.version>
    </properties>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <!--SpringCloud全局依赖管理-->
    <dependencyManagement>
        <dependencies>
            <!--cloud-->
            <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>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

 

 

4.创建eureka服务端,在父项目下面创建一个子项目eureka-services,pom文件为:

    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>eureka</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>maven-eureka</name><!--此name为maven中的模块名-->
    <description>eureka-services的描述</description>
   <!--引入父依赖,这里因为dafu-spring-cloud统一管理,所以引入了父依赖-->
    <parent>
        <groupId>com.example.dafu</groupId>
        <artifactId>springcloud</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
  <!--eureka的服务端 -->
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

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

eureka的配置文件我这里使用application.properties(别人都用yml,我比较喜欢priperties):

server.port=8761
spring.application.name=eureka-server
eureka.instance.hostname=127.0.0.1

# false代表不向注册中心注册自己
eureka.client.register-with-eureka=false

# 是否需要从注册中心检索获取服务的注册信息。默认值为true
# 单机版的可设置成false,集群版的由于需要同步其他节点的服务注册数据,故设成true。
eureka.client.fetch-registry=false

# 是否开启自我保护模式,默认值true
# eureka server默认在运行期间会去统计心跳失败比例在 15 分钟之内是否低于 85%,如果低于 85%,
# Eureka Server 会将这些实例保护起来,让这些实例不会过期,
# 但是在保护期内如果服务刚好这个服务提供者非正常下线了,此时服务消费者就会拿到一个无效的服务实例,此时会调用失败
#
设置为false可以确保注册中心中不可用的实例被及时的剔除。
eureka.server.enable-self-preservation=false
# 清理无效节点的时间间隔,缺省 (1000*60)ms
eureka.server.eviction-interval-timer-in-ms=6000
# 当获取不到对应实例时,需要等待的时间,缺省 (1000*60*5)ms
eureka.server.wait-time-in-ms-when-sync-empty=6000
# eureka监控平台地址
eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka

eureka启动类添加@EnableEurekaServer即可:

 

 

 然后启动eureka,访问localhost:8761,会看到eureka启动成功:

 

 

5.有了eureka的服务端,接下来我们创建两个客户端provider-services和practice-services,端口号分别是8081和8082,provider-services与practice-services配置文件相同,只区别于端口 然后启动类加@EnableEurekaClient注解即可:

server.port=8081
spring.application.name=provider-server
eureka.client.serviceUrl.defaultZone=http://127.0.0.1:8761/eureka

server.port=8082
spring.application.name=provider-server
eureka.client.serviceUrl.defaultZone=http://127.0.0.1:8761/eureka

 

pom文件(两个一样,这里写一个就好):

<modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>practice</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>maven-practice</name><!--此name为maven中的模块名-->
    <description>practice-services的描述</description>
    <!--引入父依赖-->
    <parent>
        <groupId>com.example.dafu</groupId>
        <artifactId>springcloud</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <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-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
    </dependencies>

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

 

接下来启动这俩服务,我们看到了控制台信息显示两个服务注册到了eureka:

 

 

 我们在访问localhost:8761会看到两个服务都注册到了eureka:

 

 

 

 

 

6.eureka整合完了,我们的服务注册和发现都可以实现了,这里有个问题就是我们分别去请求两个服务的接口,都可以请求到,并没有统一的访问api,所以我们需要整合gateway,整合gateway之前我们先了解下gateway。

pring Cloud Gateway是由spring官方基于Spring5.0、Spring Boot2.x、Project Reactor等技术开发的网关,目的是代替原先版本中的Spring Cloud Netfilx Zuul,目前Netfilx已经开源了Zuul2.0,但Spring没有考虑集成,而是推出了自己开发的Spring Cloud GateWay。该项目提供了一个构建在Spring Ecosystem之上的API网关,旨在提供一种简单而有效的途径来发送API,可提供请求路由、协议转换、安全认证、服务鉴权、流量控制、日志监控等服务(具体可以查看官网http://spring.io/projects/spring-cloud-gateway)

gateway网关处理流程图如下:

 

 

 

6.1:请求发送到网关,DispatcherHandler是Http请求的中央分发器,将请求匹配到相应的HandlerMapping;

6.2:请求和处理器之间有一个映射关系,网关将会对请求进行路由,handler会匹配                       RoutePredicateHandlerMapping,以匹配到对应的Route;

6.3:经过RoutePredicateHandlerMapping处理后,请求会发送到Web处理器,该WebHandler代理了一系列网关过滤器和全局过滤,此时会对请求或者响应头进行处理;

6.4:最后转发到具体的代理服务;

DispatcherHandler--->RoutePredicateHandlerMapping

RoutePredicateHandlerMapping---->FilteringWebHandler

FilteringWebHandler----->DefaultGatewayFilterChain

6.5:Gateway与Zuul:

 

 

 

 

6.6:接下来创建gateway-services子项目,引入依赖:

    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>gateway</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>maven-gateway</name><!--此name为maven中的模块名-->
    <description>gateway-services的描述</description>
    <!--引入父依赖-->
    <parent>
        <groupId>com.example.dafu</groupId>
        <artifactId>springcloud</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

6.7配置文件添加,并且在启动类添加@EnableEurekaClient:

server.port=8765
spring.application.name=gateway-server

# 当新加了服务时,不用去配置路由规则和重启网关gateway也能转发
#是否与服务注册于发现组件进行结合,通过 serviceId 转发到具体的服务实例。
# 默认为 false,设为 true 便开启通过服务中心的自动根据 serviceId 创建路由的功能。
spring.cloud.gateway.discovery.locator.enabled=false

# 开启小写验证,默认feign根据服务名查找都是用的全大写
spring.cloud.gateway.discovery.locator.lower-case-service-id=true

# 注册中心地址
eureka.client.serviceUrl.defaultZone=http://127.0.0.1:8761/eureka

# true将IP注册到Eureka,false将机器的主机名注册到Eureka
eureka.instance.prefer-ip-address=true

# 设置spring.cloud.gateway.routes,需将spring.cloud.gateway.discovery.locator.enabled改为false
# 如果不改的话,localhost:8765/provider-server/controller/index请求服务地址也能正常访问,
# 因为这时为每个服务创建了2个router。
# 路由id:自定义。
# 路由uri:从eureka获取服务,且以lb(load-balance)负载均衡方式转发
# 路由断言:Path的predicates,将以/provider/**开头的请求都会转发到uri为lb://provider-server的地址上
# 路由filters:用StripPrefix的filter 在转发之前将/provider去掉
# provider服务
spring.cloud.gateway.routes[0].id=provider-server
spring.cloud.gateway.routes[0].uri= lb://provider-server
spring.cloud.gateway.routes[0].predicates[0]= Path=/provider/**
spring.cloud.gateway.routes[0].filters[0]= StripPrefix=1
# practice服务
spring.cloud.gateway.routes[1].id=practice-server
spring.cloud.gateway.routes[1].uri= lb://practice-server
spring.cloud.gateway.routes[1].predicates[0]= Path=/practice/**
spring.cloud.gateway.routes[1].filters[0]= StripPrefix=1

6.8:启动gateway模块,输入localhost:8765访问routes后面配置的predicates的path:

 

 和

 

 我们可以看到两个模块的服务可以通过api网关来统一访问了,最终项目结构:

 

 

 



posted @ 2020-04-15 00:23  一步一高  阅读(4530)  评论(0编辑  收藏  举报