SpringCloud的一些组件

SpringCloud

1.应用架构的转变

1.1 单体架构

优点:易于开发(架构简单、技术成本低)、易于测试(所有的功能在一个项目)、易于部署(部署在一个tomcat上面)。

缺点:代码臃肿不方便维护、耦合度高、技术选型单一、无法对某一业务做扩展(集群)、系统扩展性能就变差。

1.2 分布式

分布式就是把单个应用分成多个子应用,多个子应用部署在不同的服务器,组成一个完整的系统,所有的服务需要相互通信、相互协调,缺一不可。如果子系统的压力依然很大,可以对子系统做集群。

1.3 面向服务的架构SOA

就是在分布式的基础上,分为表现层和服务层,把服务层暴露出来,然后服务层之间进行调用和通信。

1.4 微服务

微服务架构就是在SOA的基础上,每个子服务独立于自己的进程中,每个子服务之间通过http进行通信。不同的服务可以使用不同的语言,不同的服务可以使用不同的数据库。

特点:有多个服务组成的完整系统,每个服务之间都是相互独立的,系统之间通过http进行通信,每个系统都可以使用不用的开发语言,并且每个子系统也可以使用不同的数据库,微服务是一个分布式系统。

优点:易于维护、耦合性低、更强大的系统负载能力和集群能力、拓展功能比较强、不同的服务使用不同的语言。

缺点:技术成本比较高、分布式事务

1.5 什么是集群?

为了提升系统的业务作业能力、和防止单点故障,我们会对系统做集群,就是复制项目,然后做同样的事情,每个项目一个tomcat,一个tomcat挂了,就可以用另一个,防止了单点故障。

1.6 什么是负载均衡?

负载均衡就是设置了集群过后,产生的另一个问题,就是集群之间所处理业务的量,需要达到一个均衡的状态,不能让一个tomcat承受很多的并发,另一个tomcat承受很少的并发量,所以需要设置负载均衡(需要设置负载均衡器)。

mark

这里的Nginx就是一个负载均衡器,它可以按照某种算法(轮询,ip_hash等等)将请求路由到不同的后端服务器上,同类型的负载均衡器还有如“HAproxy”,“LVS”等

2.SpringCloud简介

2.1 基本概念

SpringCloud是基于SpringBoot实现的一个服务治理工具包,用于在微服务架构中进行管理和协调服务的。

2.2 常用组件

img

2.3 服务通信协议
1.RPC

RPC(Remote Produce Call)远程过程调用,类似的还有RMI。自定义数据格式,基于原生TCP通信,速度快,效率高。早期的webservice,现在热门的dubbo,都是RPC的典型

2.HTTP

Http其实是一种网络传输协议,基于TCP,规定了数据传输的格式。现在客户端浏览器与服务端通信基本都是采用Http协议。也可以用来进行远程服务调用。缺点是消息封装臃肿。 现在热门的Rest风格,就可以通过http协议来实现

2.4 SpringCloud与Dubbo的区别

早期在国内做分布式(微服务)应用Dubbo是比较热门的框架,被许多互联网公司所采用,并产生了许多衍生版本,如网易,京东,新浪,当当等等,奈何在2014年10月Dubbo停止维护,在Dubbo停更的时间里Spring Cloud快速追赶上。在2017年9月,阿里宣布重启Dubbo项目,计划对Dubbo进行持续更新维护。2018.2月,阿里将Dubbo捐献给Apache基金会,Dubbo成为Apache孵化器项目。

所以当前微服务架构,Dubbo和SpringCloud比较火,另外还有Thrift、gRPC等等 。很多人把SpringCloud 和Dubbo进行对比,其实两个框架并没有太大的可比性,因为他们的定位不同。Spring Cloud是一个完整的微服务解决方案,它提供了微服务各问题的解决方案集合,而Dubbo是一个高性能的RPC框架,它有着很多功能的缺失。

定位不一样

SpringCloud为了微服务的落地提供了一套完整的组件,而Dubbo只是一个RPC框架,缺失的功能很多。

通信协议不一样

Dubbo的通信方式是RPC,基于原声的tcp,性能较好,而SpringCloud的通信方式基于Http协议,虽然底层基于tcp,但是Http的封装过于臃肿,但是使用Http好处在于互相通信的两个服务可以使用不同的变成语言去编写,只要他们都支持Http通信即可互相调用,而Dubbo只支持Java,当然Dubbo交给Apache维护之后做了升级,Dubbo在以后不仅仅支持Java。

背景都很强大

Dubbo背靠阿里和Apache,淘宝就是使用的Dubbo来开发经理过双“11”期间的高并发大流量检验,可以说是非常的稳定和成熟,SpringCloud是Spring家族的成员,严格遵循Martin Fowler提出的微服务规范,可以认为SpringCloud是微服务架构的标准,总之两者背景都很强大,文档完善,社区活跃,所以不管作何选择,都是很有前途的。

开发风格

从开发风格上来讲,Dubbo官方推荐倾向于使用Spring xml配置方式,SpringCloud是基于SpringBoot的开发风格,即采用注解的方式进行配置,从开发速度上来说,SpringCloud具有更高的开发和部署速度。

3.Eureka服务注册与发现

3.1 Eureka的工作原理
  1. 服务注册:Eureka是一个服务注册于发现组件,统一管理微服务的通信地址,每个微服务都要注册在Eureka上面。分为 EurekaServer 服务端(注册中心)和 EurekaClient 客户端。

  2. 服务发现:本地客户端会定期(默认为30秒)向注册中心缓存一份注册表到本地,然后一个微服务调用另一个微服务的时候,会通过注册表找到对应服务的通信地址,然后根据通信地址基于http发送请求。

  3. 服务续约:每个微服务会每隔30秒(默认)向注册中心发送心跳请求,完成服务续约,证明自己还存在。如果未向注册中心续约(说明宕机或发生其他事请了),那么就会剔除掉该服务,当然一次没有续约并不会立即剔除掉该服务,如果3此没续约(也就是90秒)就会进行剔除。

  4. 服务下线:当服务关闭的时候会向注册中心发送下线请求,然后注册中心就会在注册表里面把该服务剔除掉。

4.多模块项目搭建

创建一个项目,只留pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>cn.itsource</groupId>
    <artifactId>SpringCloud-parent</artifactId>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>Service-Eureka</module>
        <module>Service-User</module>
        <module>Service-Order</module>
    </modules>
    <packaging>pom</packaging>
    <!--公共的一些配置-->
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.SR1</spring-cloud.version>
    </properties>

    <!--1.管理 SpringBoot的jar包-->
    <parent>
        <groupId> org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.5.RELEASE</version>
    </parent>


    <!--2.管理 SpringCloud的jar包
    -->
    <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>

    <!--3.这里是所有子项目都可以用的jar包-->
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>
4.1 搭建Eureka-Server
1.创建子项目Eureka-Server
2.导包
<dependencies>
        <!--spring-cloud-starter-netflix-eureka-server -->
        <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>
3.配置application.yml
server:
  port: 1010  #端口
eureka:
  instance:
    hostname: localhost #主机
  client: #客户端配置
    registerWithEureka: false  #EurekaServer自己不要注册到EurekaServer自己 ,只有EurekaClient才注册
    fetchRegistry: false  #EurekaServer不要拉取服务的通信地址列表 ,只有EurekaClient才拉取地址列表
    serviceUrl:  #注册中心的注册地址
      defaultZone: http://localhost:1010/eureka/  #http://${eureka.instance.hostname}:${server.port}/eureka/
  server:
    enable-self-preservation: false #关闭自我保护警告
4.创建app入口文件
/**
 * 注册中心启动类
 * @EnableEurekaServer : 开启EurekaServer服务端
 */
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApp
{
    public static void main( String[] args )
    {
        SpringApplication.run(EurekaServerApp.class);
    }
}
5.运行
4.2 搭建service-order服务
1.创建子项目service-order
2.导包
 <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
3.配置yml配置文件
#注册到EurekaServer
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:1010/eureka/ #注册中心地址
  instance:
    prefer-ip-address: true #指定ip地址
    instance-id: www.order.com:1020 #创建实例名
spring:
  application:
    name: order-server
server:
  port: 1020
4.创建入口文件
/**
 * 注册中心启动类
 * @EnableEurekaServer : 开启EurekaServer服务端
 */
@SpringBootApplication
@EnableEurekaClient
public class OrderServerApp
{
    public static void main( String[] args )
    {
        SpringApplication.run(OrderServerApp.class);
    }
}
5.运行

5.Eureka的CAP理论

​ 1. 一致性(Consistency):可以理解为分布式中存在多个数据副本,当其中某个数据副本发生数据更新需要实时同步到其他节点上。多个节点数据总是保持一致。例如:同一个数据同时存在于A服务器和B服务器,那么当A服务器的数据发生改变,B服务器的数据始终保持同步。

  1. 可用性(Availability): 客户端在任何时候访问集群,请求都可以正常返回结果,可以允许有一定的延迟。

  2. 分区容错性(Partition tolerance):能够容忍当服务之间通信发生故障,整个集群别分割为多个无法相互通信的分区的情况。即当集群因为网络故障被划分为多个分区,集群仍然可用。

    但是鱼和熊掌不能兼得,只能兼顾两者。

6.RestTemplate

6.1 RestTemplate介绍

微服务的通信协议主流有RPC、http,SpringCloud是基于http restful风格,而发起http请求的方式有很多。就是通过apache的httpClient、okhttp等,但spring为我们提供了一个非常简单的http请求的工具RestTemplate,他可以实现服务之间的通信。但值得注意的是RestTemplate不具备负载均衡和服务发现的能力(可以通过ribbon设置让他有负载均衡的能力),他是通过ip+端口向服务器发起调用的。

6.2 RestTemplate服务通信步骤
  1. 搭建公共User模块。

  2. 用户和订单服务添加公共user模块的依赖。

  3. 把restTemplate交给Spring管理(启动类里面创建bean),并且注入到订单服务里面。

  4. 使用restTemplate让订单服务调用用户服务 。

@RestController
public class OrderController {
    @Autowired
    RestTemplate restTemplate;
    @GetMapping("/order/{id}")
    public UserDto getUserDto(@PathVariable("id")Long id){
       //创建调用服务的url地址
        String url="http://localhost:1030/user/"+id;
        return restTemplate.getForObject(url,UserDto.class);
    }
}

7. Ribbon

7.1 Ribbon介绍

ribbon是做集群之后产生的问题的一种解决方案。就是说做了集群之后,同样的服务就有多个了,那么到底该调用哪一个呢?那就需要一个组件了,就是负载均衡的组件。

而ribbon是一个负载均衡客户端,他的主要功能是提供负载均衡算法,可以使用负载均衡算法对多个服务进行调用,帮我们做请求的分发,决定到底用这个集群的哪一个服务。

7.2 Ribbon的工作原理

ribbon通过通信地址找到某个服务的时候,假如这个通信地址所对应的服务做了集群,那么就会有多个相同的服务,那么如何选择呢?ribbon就会通过默认的负载均衡算法(默认是轮循算法,可以设置其他算法)选择一个服务进行调用。

7.3 Ribbon服务通信步骤
  1. 搭建公共User模块。

  2. 用户和订单服务添加公共user模块还有Ribbon的依赖。

  3. 把RestTemplate交给Spring管理(启动类里面创建bean),并且开启负载均衡(加上注解@loadbalanced),这样RestTemplate就有了负载均衡的能力了。

  4. RestTemplate通过服务实例名调用另一个服务。

@RestController
public class OrderController {
    @Autowired
    RestTemplate restTemplate;
    @GetMapping("/order/{id}")
    public UserDto getUserDto(@PathVariable("id")Long id){
       //创建调用服务的url地址
        //使用ribbon的方式
        String url="http://USER-SERVER/user/"+id;
        return restTemplate.getForObject(url,UserDto.class);
    }
}

8. OpenFeign

是一个声明式的http客户端,可以发送http请求。底层是基于ribbon的

8.1 feign工作原理

当启动文件配置了开启feign的注解过后,程序启动后,他就会扫描指定包下的所有带有@feignclient的注解的接口,并把他们交给spring进行管理。当服务发起请求过后,spring会使用动态代理的方式代理接口,并且会为接口每一个方法生成一个requestTemplate,然后封装一些http信息,如url地址和一些请求参数等,最终会生成一个request请求,并且把请求交给http客户端,然后http客户端会把他交给loadbalancedclient,最终ribbon的负载均衡会进行调用。

8.2 使用OpenFeign进行服务通信
  1. 创建支付服务

  2. 导入依赖

     <!--1.导入EurekaClient的包-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
            <!--2.导入Feign的包-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-openfeign</artifactId>
            </dependency>
            <!--web包-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
  3. 创建applicaton.yml配置到注册中心

    #注册到EurekaServer
    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:1010/eureka/
      instance:
        prefer-ip-address: true
        instance-id: www.pay.com:1040
    spring:
      application:
        name: pay-server
    server:
      port: 1040
    
  4. 创建启动类-需要启动注解@EnableFeignClients和@SpringBootApplication

    @SpringBootApplication
    //开启注册中心的注解
    @EnableEurekaClient
    //开启openfeign的注解
    @EnableFeignClients
    public class PayServerApp
    {
        public static void main( String[] args )
        {
            SpringApplication.run(PayServerApp.class);
        }
    }
    
  5. 创建openfeign的user客户端

    @FeignClient(value = "USER-SERVER")//客户端服务名
    public interface UserFeignClient {
        @GetMapping("/user/{id}")
        UserDto getUserDto(@PathVariable("id")Long id);
    }
    //注意:GetMapping的url地址还有参数、返回值、服务名必须存在,不存在就会找不到。
    
  6. 控制层调用用户服务-需要注入useropenFeign客户端,然后使用客户端的方法进行通信。他的底层自动会帮你拼接url地址。

    @RestController
    public class PayController {
        @Autowired
        UserFeignClient userFeignClient;
        @GetMapping("/pay/{id}")
        public UserDto getById(@PathVariable("id")Long id){
            return userFeignClient.getUserDto(id);
        }
    }
    

9.熔断器Hystrix

9.1 熔断器简介
9.2 熔断器的产生原因

在微服务里面,服务的调用是非常复杂的,一次请求往往伴随着很长的调用链,一旦调用链里面的服务有一个产生故障,就有可能导致整个调用链的故障,甚至导致整个服务的异常。所以就产生出了熔断器。

9.3 熔断器的功能
  1. 资源隔离

    资源隔离分为线程池隔离信号量隔离,就是限制请求的数量

    线程池隔离(异步):就是创建一个线程池来限制请求的数量,当有请求进来时,会为当前请求分配一个进程,请求完后返回给线程池,当线程池没有线程对象可供分配的时候,可以设置队列进行排队,如果队列中也满了,那就触发降级机制,快速失败。

    并发:线程最大数+队列数。

    开销:有线程的切换,性能消耗大

    信号量隔离(同步):就是用信号量限制请求数,进来一个,计数器加一,出去一个计数器减一,当计数器达到指定的信号量时,就不再继续加入请求,就会触发降级机制,快速失败。

    并发量:就是信号量最大值

    开销:无线程的切换,性能消耗较小。

  2. 服务熔断

    正常情况下,断路器处于闭合状态,当服务多次发生异常或者请求超时等情况的时候,服务会将降级数据返回,快速失败。并且自身会标记熔断。过了一段时间过后,会达到半熔断状态,接收一些少量请求,如果请求还是失败,那么就会回到熔断状态,如果请求成功,那么就会重新回到电路闭合状态。

    img

  3. 降级机制

    请求异常的时候,会返回降级方法的数据。

  4. 缓存

    第一次请求的时候,对请求做缓存,第二次请求的时候,会直接拿到缓存数据,这样就提高了请求数据的效率。

9.3 设置降级方法的步骤
  1. 导入熔断器的依赖
<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
  1. 入口类添加开启熔断器注解@EnableCircuitBreaker
@SpringBootApplication
@EnableEurekaClient
//开启熔断器注解
@EnableCircuitBreaker
public class OrderServerApp
{
    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
    public static void main( String[] args )
    {
        SpringApplication.run(OrderServerApp.class);
    }
}
  1. 声明降级方法
@HystrixCommand(fallbackMethod = "defaultStores")
    public Object getStores(Map<String, Object> parameters) {
        //do stuff that might fail
    }
  1. 设置降级方法,降级方法的返回值还有参数必须和被降级方法一致。
public Object defaultStores(Map<String, Object> parameters) {
        return /* something useful */;
    }
9.4设置feign开启熔断器
  1. application.yml里面配置feign开启熔断器
feign:
  hystrix:
    enabled: true #开启熔断支持
  1. 在feign客户端接口设置降级类

    @FeignClient(value = "USER-SERVER",fallbackFactory = UserFeignClientFallbackFactory.class)
    public interface UserFeignClient {
        @GetMapping("/user/{id}")
        UserDto getUserDto(@PathVariable("id")Long id);
    }
    
  2. 创建降级类,实现接口(降级类要打@component注解,Spring才能扫描)

    @Component
    public class UserFeignClientFallbackFactory implements FallbackFactory<UserFeignClient>{
        @Override
        public UserFeignClient create(Throwable throwable) {
            return new UserFeignClient() {
                @Override
                public UserDto getUserDto(Long id) {
                    throwable.printStackTrace();
                    return new UserDto(0l,"抱歉,无此用户","爱您!");
                }
            };
        }
    }
    

    4.测试

10.网关zuul

10.1 简介

zuul是一个微服务的大门,要想请求微服务就必须先经过他,类似过滤器,可以做登录验证、限流等。他负责分发请求、监控、弹性等。zuul本身也是个服务,所以他需要对服务进行发行,所以集成了hystrix,还需要把请求分发到其他的微服务,所以需要继承ribbon,又因为他需要把请求分发到其他微服务,进行服务与发现,去拉取注册表,所以还需要注册中心Euraka。

10.2 源码剖析

img

当浏览器发送请求过后,先进入zuul网关,然后网关要对请求进行过滤,先要走一个前置过滤器,然后再走路由过滤器,路由过滤器分发请求,然后再响应出一些数据给路由过滤器,路由过滤器再经过后置过滤器,后置过滤器再从网关出去。如果过滤器出现了异常,就会走一个异常过滤器,处理完异常过后,就会把请求交给后置过滤器,后置 过滤器进行返回。

10.3 自定义前置过滤器
  1. 先导入依赖:zuul、ribbon、eureka、web、hystrix的包

    <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
            </dependency>
        </dependencies>
    

    2.配置application.yml文件

    #注册到EurekaServer
    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:1010/eureka/
      instance:
        prefer-ip-address: true
        instance-id: www.zuul.com:1050
    spring:
      application:
        name: zuul-server
    server:
      port: 1050
    feign:
      hystrix:
        enabled: true #开启熔断支持
    hystrix:
      command:
        default:
          execution:
            isolation:
              thread:
                timeoutInMilliseconds: 2000
    zuul:
      prefix: "/cloud"
      ignoredServices: '*'
      routes:
        order-server: "/orders/**"
        pay-server: "/pays/**"
        user-server: "/users/**"
    

    因为zuul是对请求进行转发的,所以我们输入地址的时候都是输入的zuul的地址,然后zuul再把请求分发到各个服务,比如访问localhost:网关端口/cloud/orders/**的时候,他就会分发到服务名为order-server的服务。

    3.设置启动文件

    @SpringBootApplication
    @EnableEurekaClient
    //开启网关注解
    @EnableZuulProxy
    public class ZuulServerApp
    {
        public static void main( String[] args )
        {
            SpringApplication.run(ZuulServerApp.class);
        }
    }
    

    4.创建登录过滤器,实现ZuulFilter接口

    //定义登录检查的filter
    @Component
    public class LoginCheckFilter extends ZuulFilter {
    
        @Override
        public String filterType() {
            //前置
            return FilterConstants.PRE_TYPE ; //"pre";
        }
    
        @Override
        public int filterOrder() {
            //顺序
            return 0;
        }
    
        @Override
        public boolean shouldFilter() {
            //是否执行Run方法 , 如果url是  /login , /register 就不执行Run方法,返回false
            //1.获取请求对象
            HttpServletRequest request = RequestContext.getCurrentContext().getRequest();
            //2.获取URL
            String requestURI = request.getRequestURI();
            System.out.println("requestURI:"+requestURI);
            //3.判断ULR是否是 /login , /register
            //用来匹配URL的工具
            AntPathMatcher antPathMatcher = new AntPathMatcher();
            if(antPathMatcher.match(requestURI , "/cloud/orders/login") ||
                    antPathMatcher.match(requestURI , "/cloud/orders/register")){
                //3.1.是就返回false
                return false;
            }
            //3.2.不是就返回true
            return true;
        }
    
        @Override
        public Object run() throws ZuulException {
            //做登录检查的核心业务逻辑 , 检查请求头中的Token
            //1.获取请求对象
            HttpServletRequest request = RequestContext.getCurrentContext().getRequest();
            HttpServletResponse response = RequestContext.getCurrentContext().getResponse();
            response.setContentType("application/json;charset=utf-8");
    
            //2.获取请求头中的Token
            String token = request.getHeader("token");
            //3.如果么有Token
            if(StringUtils.isEmpty(token)){
                //3.1.封装一个错误信息
                Map<String,Object> result = new HashMap<>();
                result.put("success",false);
                result.put("message","滚去登录");
                try {
                    //错误码,授权失败
                    response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                    response.getWriter().print(JSON.toJSONString(result));
                } catch (IOException e) {
                    e.printStackTrace();
                }
                //3.2.告诉zuul不要继续执行了: 阻止放行
                RequestContext.getCurrentContext().setSendZuulResponse(false);
            }
            return null;
        }
    }
    

11.配置中心Config

11.1 什么是配置中心

就是把所有微服务的配置文件进行统一管理,修改配置文件无需重启服务。

11.2 配置中心工作流程
img

configServer本身也是个微服务,他需要向注册中心注册地址。工作流程就是微服务通过configclient向配置中心发起请求,然后配置中心会在gitee上面获取配置,然后将配置返回给微服务。

11.3 配置步骤
  1. 创建gitte仓库

  2. 创建本地配置中心service-config

  3. 把网关服务和订单服务的配置文件交给gitee仓库

  4. 本地配置中心配置注册中心和giite地址,开启配置注解@EnableConfigServer。

    @SpringBootApplication
    @EnableEurekaClient
    //开启配置中心注解配置
    @EnableConfigServer
    public class ConfigServerApp
    {
        public static void main( String[] args )
        {
            SpringApplication.run(ConfigServerApp.class);
        }
    }
    

    bootstap.yml(bootstap.yml的优先级要高于application.yml)

    #注册到EurekaServer
    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:1010/eureka/
      instance:
        prefer-ip-address: true
        instance-id: www.config.com:1060
    spring:
      application:
        name: config-server
      cloud:
        config:
          server:
            git:
              uri: https://gitee.com/zhangjiaxiangSG/spring-cloud-config.git
              username: git账号
              password: git密码
    server:
      port: 1060
    
  5. zuul网关创建bootstrap.yml,并且配置配置中心的地址

    spring:
      cloud:
        config:
          uri: http://localhost:1060
          name: application-zuul
          profile: dev
    
  6. 订单服务创建bootstrap.yml,并且配置配置中心的地址

    spring:
      cloud:
        config:
          uri: http://localhost:1060
          name: application-pay
          profile: dev
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值