SpringBoot&&SpringCloud学习笔记

疑问
既然已经引入了spring-boot-starter-parent作为父工程,为什么还需要加父工程 里已有的打包插件,同理spring-boot-dependencies也已经添加好依赖了,为什么在自己的springboot项目还要加依赖

  • spring-boot-dependencies中的依赖是放在<dependencyManagement>标签中的,如果子项目没有声明依赖,这些在<dependencyManagement>标签中的依赖是不会自动引入在子项目的。

疑问

使用了thymeleaf模板引擎技术的的HTML页面也是通过model对象传递数据到前端页面,和JSP技术好像也是一样,具体有什么区别?

疑问

springboot为什么可以打成jar包,直接运行?

  • 内部引用了tomcat,实际上也是通过tomcat来启动项目

SpringBoot😊

为什么要有SpringBoot?

  • 使用原先的SSM方式去搭建项目效率较低,需要配置大量的依赖和配置文件,以及考虑依赖之间的兼容性问题。
  • 有了SpringBoot就可以简化项目的配置和依赖的使用,提高开发效率

约定优于配置(Convention over Configuration),又称按约定编程,是一种软件设计范式。

本质上是说,系统、类库或框架应该假定合理的默认值,而非要求提供不必要的配置。比如说模型中有一个名为User的类,那么数据库中对应的表就会默认命名为user。只有在偏离这一个约定的时候,例如想要将该表命名为person,才需要写有关这个名字的配置。

Spring优缺点分析

优点:

Spring是Java企业版(Java Enterprise Edition,JEE,也称J2EE)的轻量级代替品。无需开发重量级的Enterprise Java Bean(EJB),Spring为企业级Java开发提供了一种相对简单的方法,通过依赖注入和面向切面编程,用简单的Java对象(Plain Old Java Object,POJO)实现了EJB的功能。

缺点:

  • 虽然Spring的组件代码是轻量级的,但它的配置却是重量级的**。一开始,Spring用XML配置,而且是很多XML配 置。Spring 2.5引入了基于注解的组件扫描,这消除了大量针对应用程序自身组件的显式XML配置。Spring 3.0引入 了基于Java的配置,这是一种类型安全的可重构配置方式,可以代替XML。所有这些配置都代表了开发时的损耗。因为在思考Spring特性配置和解决业务问题之间需要进行思维切换,所以编写配置挤占了编写应用程序逻辑的时间。和所有框架一样,Spring实用,但与此同时它要求的回报也不少。

  • 项目的依赖管理也是一件耗时耗力的事情。在环境搭建时,需要分析要导入哪些库的坐标,而且还需要分析导入与之有依赖关系的其他库的坐标,一旦选错了依赖的版本,随之而来的不兼容问题就会严重阻碍项目的开发进度

  • SSM整合:Spring、Spring MVC、Mybatis、Spring-Mybatis整合包、数据库驱动,引入依赖的数量繁多、容易存在版本冲突。

SpringBoot的两大特点

  • 起步依赖
    • 起步依赖本质上是一个Maven项目对象模型(Project Object Model,POM),定义了对其他库的传递依赖,这些东西加在一起即支持某项功能。
    • 也就是每个springboot项目都会依赖一个配置好的springboot父工程,父工程已经做好了依赖的版本控制,编码格式等默认配置
  • 自动配置
    • springboot会自动将一些配置类的bean注册进ioc容器,我们可以需要的地方使用@autowired或者@resource等注解来使用它。如果需要个性化的配置只需要在application.yml文件中配置即可。

SpringBoot快速入门

  • POM文件

    <!--
        所用的springBoot项目都会直接或者间接的继承spring-boot-starter-parent 
        1.指定项目的编码格式为UTF-8 
        2.指定JDK版本为1.8 
        3.对项目依赖的版本进行管理,当前项目再引入其他常用的依赖时就需要再指定版本号,避免版本 冲突的问题
        4.默认的资源过滤和插件管理 
    --> 
    <parent> 
        <groupId>org.springframework.boot</groupId> 
        <artifactId>spring-boot-starter-parent</artifactId> 
        <version>2.3.4.RELEASE</version> 
    </parent> 
    
    <dependencies> 
        <!--引入Spring Web及Spring MVC相关的依赖--> 
        <dependency>
            <groupId>org.springframework.boot</groupId> 
            <artifactId>spring-boot-starter-web</artifactId> 
        </dependency> </dependencies> 
    
    <!--可以将project打包为一个可以执行的jar--> 
    <build> 
        <plugins> 
            <plugin>
                <groupId>org.springframework.boot</groupId> 
                <artifactId>spring-boot-maven-plugin</artifactId> 
            </plugin> 
        </plugins> 
    </build>
    
  • 启动类

    /**
     * SpringBoot的启动类通常放在二级包中,比如:com.lagou.SpringBootDemo1Application 
     * 因为SpringBoot项目在做包扫描,会扫描启动类所在的包及其子包下的所有内容。 
     */ 
    
    //标识当前类为SpringBoot项目的启动类 
    @SpringBootApplication 
    public class SpringBootDemo1Application { 
        public static void main(String[] args) { 
            //样板代码 
            SpringApplication.run(SpringBootDemo1Application.class,args); 
        }
    }
    
  • Controller

    @RestController 
    @RequestMapping("/hello") 
    public class HelloController { 
        @RequestMapping("/boot") 
        public String helloBoot(){ 
            return "Hello Spring Boot"; 
        } 
    }
    
  • 默认启动项目的端口是8080,可以在application.yml文件中修改

单元测试

  • 在pom.xml文件中添加测试依赖

    <dependency> 
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency> 
    
  • 测试类

    /**
     * SpringJUnit4ClassRunner.class:Spring运行环境 
     * JUnit4.class:JUnit运行环境 
     * SpringRunner.class:Spring Boot运行环境 
     */ 
    @RunWith(SpringRunner.class) //@RunWith:运行器 
    @SpringBootTest //标记为当前类为SpringBoot测试类
    class Springbootdemo2ApplicationTests { 
        /*** 需求:调用HelloController的hello方法 */ 
        @Autowired private HelloController helloController;
        @Test void contextLoads() {
            String result = helloController.hello(); 
            System.out.println(result);
        } 
    }
    

热部署:在修改完代码之后,不需要重新启动容器,就可以实现更新。

使用步骤

1)添加SpringBoot的热部署依赖启动器

2)开启Idea的自动编译

3)开启Idea的在项目运行中自动编译的功能

  • POM文件

    <!-- 引入热部署依赖 --> 
    <dependency> 
        <groupId>org.springframework.boot</groupId> 
        <artifactId>spring-boot-devtools</artifactId>
    </dependency>
    
  • IDEA工具热部署设置

    选择IDEA工具界面的【File】->【Settings】选项,打开Compiler面板设置页面

    <img src="https://raw.githubusercontent.com/RogerJack-ace/picgo/master/image-20201018173958066.png" />

  • 在项目任意页面中使用组合快捷键“Ctrl+Shift+Alt+/”打开Maintenance选项框,选中并打开Registry页面,

[图片上传失败...(image-803e98-1603627257896)]

使用application.yml文件给bean对象注入数据

  • 实体类
@Component
//将配置文件中所有以person开头的配置信息注入当前类中 
//前提1:必须保证配置文件中person.xx与当前Person类的属性名一致 
//前提2:必须保证当前Person中的属性都具有set方法
@ConfigurationProperties(prefix = "person") 
public class Person {
    private int id; //id 
    private String name; //名称 
    private List hobby; //爱好 
    private String[] family; //家庭成员 
    private Map map; 
    private Pet pet; //宠物 
    //省略了 对应属性的 set方法...
}
  • 配置文件

    #对实体类对象Person进行属性配置 
    person: 
      id: 1 
      name: 王二麻子 
      family: 
          - 妻 
          - 妾 
      hobby: 
          - play 
          - read 
          - sleep 
      map:
          k1: value1 
          k2: value2 
      pet:
          type: 狗 
          name: 哈士奇
    
  • 如果有多个配置文件,默认.properties的优先级最高,根据在父工程中引入的pom文件

  • 也可以使用@value注解给属性赋值,但是只可以给string类型的属性赋值

@Component 
public class Student { 
    @Value("${person.id}") 
    private int id; 
    @Value("${person.name}") 
    private String name; //名称 
    //省略set方法
}

自定义配置

  • 使用@PropertySource加载配置文件
    • 可以不使用spring boot默认给的配置文件,自己创建配置文件,如my.properties
#对实体类对象MyProperties进行属性配置 
test.id=110 
test.name=test

创建一个配置类MyProperties,提供test.properties自定义配置文件中对应的属性,并根据@PropertySource注解的使用进行相关配置

@Component // 自定义配置类 
@PropertySource("classpath:test.properties") // 指定自定义配置文件位置和名称 
@ConfigurationProperties(prefix = "test") // 指定配置文件注入属性前缀 
public class MyProperties { 
    private int id; 
    private String name; 
    // 省略属性getXX()和setXX()方法 
    // 省略toString()方法 }

  • 使用@Configuration编写自定义配置类
@Configuration // 定义该类是一个配置类
public class MyConfig { 
    @Bean // 将返回值对象作为组件添加到Spring容器中,该组件id默认为方法名
    public MyService myService(){ 
        return new MyService(); 
    } 
}

为什么导入dependency时不需要指定版本?

  • 每个spring boot项目都有父依赖spring-boot-starter-parent,而spring-boot-starter-parent POM文件中又引入了spring-boot-dependencies父依赖,在这个父依赖中声明了当前项目的所有可能需要的依赖的版本,所以在自己的项目中不需要指定版本,spring boot已经帮你配置好版本了

Spring Boot****到底是如何进行自动配置的,都把哪些组件进行了自动配置?

|- @SpringBootConfiguration 
    |- @Configuration //通过javaConfig的方式来添加组件到IOC容器中 
|- @EnableAutoConfiguration 
    |- @AutoConfigurationPackage //自动配置包,与@ComponentScan扫描到的添加到IOC 
    |- @Import(AutoConfigurationImportSelector.class) //到META- INF/spring.factories中定义的bean添加到IOC容器中 
|- @ComponentScan //包扫描

疑问

mybatis-plus插件的使用,没有看到sql的编写,是怎么实现的?

SpringCloud😁

项目中遇到的问题✔

  • order是关键字,不能用来作为表名
  • 使用host文件配置域名映射时,只能映射到ip上,不能加端口号,默认是80端口
  • nginx配置反向代理的时候也是需要使用80端口
  • nginx的默认轮询策略是一个接口调<b style="color:red">两次</b>再换另一个接口

@PathVariable的作用?

  • 在默认情况下,@PathVariable注解的参数可以是一些基本的简单类型:int,long,Date,String等,Spring能根据URL变量的具体值以及函数参数的类型来进行转换
  • 识别url中占位符的数据,并自动赋值到同名形参变量上

SpringCloud 核心组件

  • Eureka 注册中心
  • Ribbon 负载均衡
  • Hystrix 熔断器
  • Feign (远程调用+Ribbon+Hystrix)
  • Gateway 网关
  • Spring Cloud Config 配置中心
image

单例注册中心

  • 父工程中加入spring cloud的依赖
<!--管理依赖,主要作用是版本管理,子项目中不会自动导入管理依赖中的所有依赖,只会导入声明的依赖-->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Greenwich.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

  • eureka工程中加入eureka的依赖
<!--Eureka server依赖-->
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>

  • 配置文件application.yml
server:
  port: 9300
spring:
  application:
    name: lagou-cloud-eureka # 应用名称,会在Eureka中作为服务的id标识(serviceId)
eureka:
  instance:
    hostname: localhost
  client:
    service-url:
      # 客户端与EurekaServer交互的地址,如果是集群,也需要写其它Server的地址
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
    register-with-eureka: false # 自己就是服务不需要注册自己
    fetch-registry: false #自己就是服务不需要从Eureka Server获取服务信息,默认为true,置为false

  • 创建启动类EurekaApplication,加入注解@EnableEurekaServer
  • 访问localhost:9300

集群注册中心

  • 在单例的基础上,复制出另一个工程,把端口号+1
  • 在本地测试的时候,修改host文件
127.0.0.1 LagouCloudEurekaServerA
127.0.0.1 LagouCloudEurekaServerB

  • 修改配置文件
server:
  port: 9300
spring:
  application:
    name: lagou-cloud-eureka # 应用名称,会在Eureka中作为服务的id标识(serviceId)
eureka:
  instance:
    hostname: LagouCloudEurekaServerA
    #hostname: LagouCloudEurekaServerB 另一项目
  client:
    service-url:
      # 客户端与EurekaServer交互的地址,如果是集群,也需要写其它Server的地址
      defaultZone: http://LagouCloudEurekaServerB:9301/eureka
      #defaultZone: http://LagouCloudEurekaServerA:9300/eureka 另一项目
    register-with-eureka: false # 自己就是服务不需要注册自己
    fetch-registry: false #自己就是服务不需要从Eureka Server获取服务信息,默认为true,置为false

微服务注册到注册中心

  • 在项目中加入eureka-client的依赖
<!--Eureka client-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

  • 配置application.yaml文件
server:
  port: 9100 # 后期该微服务多实例,9000(10个以内)
spring:
  #解决bean重复注册问题
  main:
    allow-bean-definition-overriding: true
  application:
    name: lagou-service-order
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/lagou?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
    username: root
    password: 123456
  cloud:
    #config客户端配置,和ConfigServer通信,并告知ConfigServer希望获取的配置信息在哪个文件中
    config:
      name: application
      profile:
      label: master #分支名称
      uri:  http://localhost:9400 #ConfigServer配置中心地址
  #通知刷新
  rabbitmq:
    host: 192.168.64.128
    username: roger
    password: 123456
# 向注册中心声明
eureka:
  client:
    serviceUrl: # eureka server的路径
      defaultZone: http://LagouCloudEurekaServerA:9300/eureka,http://LagouCloudEurekaServerB:9301/eureka
  instance:
    #使用ip注册,否则会使用主机名注册了(此处考虑到对老版本的兼容,新版本经过实验都是ip)
    prefer-ip-address: true
    #自定义实例显示格式,加上版本号,便于多版本管理,注意是ip-address,早期版本是ipAddress
    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}:@project.version@


  • 启动类上加注解 @EnableDiscoveryClient
  • 启动后就能在注册中心发现已注册

Ribbon使用,不加Feign

使用

  1. 在消费者项目的RestTemplate方法上加@loadBalance
  2. 在提供者项目编写一个获取当前项目端口的方法,并且提供者项目做集群。
  3. 在消费者调用提供者

Hystrix

疑问

配置在application文件中的熔断器配置指定了并发执行的最大线程数和最大队列数,是所有接口用一个线程池还是每个接口用一个

Feign使用

  • 父工程引入openfeign依赖
<!--OpenFeign依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

  • 消费者启动类加上@EnableFeignClients
  • 创建一个接口,用来远程调用,需要提供者的同名方法,类上加@FeignClient("提供者注册名")
@FeignClient("lagou-service-goods",fallback = GoodFeignFallback.class)
public interface GoodFeign {
    // 要带上父路径!!!!
    @RequestMapping("/good/queryByIds")
    public List<Good> queryByIds(@RequestBody List<Integer> ids);
}

使用Feign,整合Ribbon

  • 父工程引入 OpenFeign依赖
<!--OpenFeign依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

  • 消费者项目配置文件
#针对的被调用方微服务名称,不加就是全局生效
lagou-service-goods:
  ribbon:
    #请求连接超时时间
    ConnectTimeout: 2000
    #请求处理超时时间
    ReadTimeout: 15000
    #对所有操作都进行重试
    OkToRetryOnAllOperations: true
    ####根据如上配置,当访问到故障请求的时候,它会再尝试访问一次当前实例(次数由MaxAutoRetries配置),
    ####如果不行,就换一个实例进行访问,如果还不行,再换一次实例访问(更换次数由MaxAutoRetriesNextServer配置),
    ####如果依然不行,返回失败信息。
    MaxAutoRetries: 0 #对当前选中实例重试次数,不包括第一次调用
    MaxAutoRetriesNextServer: 0 #切换实例的重试次数
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.ZoneAvoidanceRule #负载策略调整

使用Feign,整合Hystrix

  • 父工程添加hystrix依赖
<!--熔断器Hystrix-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

  • 配置消费者项目配置文件
# 配置熔断策略:
hystrix:
  command:
    default:
      circuitBreaker:
        # 强制打开熔断器,如果该属性设置为true,强制断路器进入打开状态,将会拒绝所有的请求。 默认false关闭的
        forceOpen: false
        # 触发熔断错误比例阈值,默认值50%
        errorThresholdPercentage: 50
        # 熔断后休眠时长,默认值5秒
        sleepWindowInMilliseconds: 3000
        # 熔断触发最小请求次数,默认值是20
        requestVolumeThreshold: 2
      execution:
        isolation:
          thread:
            # 熔断超时设置,默认为1秒,超过五秒还未返回结果就降级处理
            timeoutInMilliseconds: 5000
  threadpool:
    default:
      coreSize: 16 #并发执行的最大线程数,默认10
      maxQueueSize: 1000 #BlockingQueue的最大队列数,默认值-1
      queueSizeRejectionThreshold: 600 #即使maxQueueSize没有达到,达到 queueSizeRejectionThreshold该值后,请求也会被拒绝,默认值5
#开启Feign对熔断器支持
feign:
  hystrix:
    enabled: true
  #开启请求和响应的压缩设置,默认是不开启的
  compression:
    request:
      enabled: true
      mime-types: text/xml,application/xml,application/json  #默认值
      min-request-size: 2048
    response:
      enabled: true

  • 创建降级处理类,实现feign接口,加@component
@Component
public class GoodFeignFallback implements GoodFeign {
    @Override
    public List<Good> queryByIds(List<Integer> ids) {
        return Collections.EMPTY_LIST;
    }

Gateway网关

一个请求—>网关根据一定的条件匹配—匹配成功之后可以将请求转发到指定的服务地址;而在这 个过程中,我们可以进行一些比较具体的控制(限流、日志、黑白名单)

  • 单独创建网关项目,导入依赖
<!--spring boot 父启动器依赖-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-commons</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency> <!--GateWay 网关-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency> <!--引入webflux-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency> <!--日志依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </dependency> <!--测试依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--lombok工具-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.4</version>
            <scope>provided</scope>
        </dependency>
        <!--引入Jaxb,开始-->
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-core</artifactId>
            <version>2.2.11</version>
        </dependency>
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
            <version>2.2.11</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
            <version>2.2.10-b140310.1920</version>
        </dependency>
        <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>activation</artifactId>
            <version>1.1.1</version>
        </dependency>
        <!--引入Jaxb,结束-->

        <!-- Actuator可以帮助你监控和管理Spring Boot应用-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--热部署-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
        <!--链路追踪-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-sleuth</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zipkin</artifactId>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <!--spring cloud依赖版本管理-->
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Greenwich.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <!--编译插件-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>11</source>
                    <target>11</target>
                    <encoding>utf-8</encoding>
                </configuration>
            </plugin>
            <!--打包插件-->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

  • 创建application.yaml配置文件
server:
  port: 9000
eureka:
  client:
    serviceUrl: # eureka server的路径
      defaultZone: http://LagouCloudEurekaServerA:9300/eureka,http://LagouCloudEurekaServerB:9301/eureka
  instance:
    prefer-ip-address: true
    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}:@project.version@
spring:
  application:
    name: lagou-cloud-gateway
  #网关的配置
  cloud:
    gateway:
      routes: #配置路由
        - id: service-order-router
          #动态路由:从注册中心获取对应服务的实例
          uri: lb://lagou-service-order
          predicates:
            - Path=/order/**
        - id: service-goods-router
          uri: lb://lagou-service-goods
          predicates:
            - Path=/good/**
#          filters:
#            - StripPrefix=1

  • 如果要实现过滤器功能,可以继承Ordered,GlobalFilter,自定义过滤方法😁

Spring Cloud Config分布式配置中心

  • Server 端:提供配置文件的存储、以接口的形式将配置文件的内容提供出去,通过使用 @EnableConfigServer注解在 Spring boot 应用中非常简单的嵌入

  • Client 端:通过接口获取配置数据并初始化自己的应用

步骤

  1. 创建github或gitee项目,如lagou-config
  2. 上传application.yaml文件
  3. 创建Config Server项目,导入依赖
<!--eureka client 客户端依赖引入-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!--config配置中心服务端-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
        </dependency>
        <!--bus 依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bus-amqp</artifactId>
        </dependency>

  1. 配置启动类,使用注解@EnableConfigServer开启配置中心服务器功能
  2. 创建配置文件
server:
  port: 9400
#注册到Eureka服务中心
eureka:
  client:
    service-url:
      defaultZone: http://LagouCloudEurekaServerA:9300/eureka,http://LagouCloudEurekaServerB:9301/eureka
  instance:
    prefer-ip-address: true
    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}:@project.version@
spring:
  application:
    name: lagou-cloud-config
  cloud:
    config:
      server:
        #git配置:uri、用户名、密码、分支....
        git:
          uri: https://gitee.com/rogerjack/lagou-config.git  #配置git地址
          username: rogerjack
          password: 123456
          search-paths:
            - lagou-config
      label: master
  rabbitmq:
    host: 192.168.64.128
    username: roger
    password: 123456

#建议暴露所有的端口
management:
  endpoints:
    web:
      exposure:
        include: "*"

  1. 需要获取配置数据的项目都是client,需要引入config client的依赖
<!--spring cloud config client的依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-client</artifactId>
        </dependency>

  1. 把客户端项目的application配置文件改为bootstrap.yaml文件,bootstrap的优先级更高,启动项目时会先加载该级别的配置文件,并编写配置
  spring:
      cloud:
        #config客户端配置,和ConfigServer通信,并告知ConfigServer希望获取的配置信息在哪个文 件中
        config:
          name: application
          profile:
          label: master #分支名称
          uri:  http://localhost:9400 #ConfigServer配置中心地址

  1. 在controller中用@value依赖注入需要的数据
  • 为了能实现自动刷新更新的数据,还需要引入rabbitmq的组件😎
  1. 在客户端和服务端引入消息总线支持的依赖
<!--bus 依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bus-amqp</artifactId>
        </dependency>

  1. 在客户端和服务端配置
#通知刷新
  spring:
      rabbitmq:
        host: 192.168.64.128
        username: rabbitmq的用户账号
        password: 密码

  1. 客户端需要配置暴露端口
# springboot中暴露健康检查等断点接口
management:
  endpoints:
    web:
      exposure:
        include: "*"
  # 暴露健康接口的细节
  endpoint
    health:
      show-details: always

  1. 当git上的数据发生变化后,只需要用POST请求去请求服务端接口如http://127.0.0.1:9400/actuator/bus-refresh🎃就可以自动刷新所有服务端数据;如果想单独刷新某个客户端,可以在接口后面加服务名:端口号即可,如http://localhost:9006/actuator/bus-refresh/lagou-service-page:9100

使用Nginx实现GateWay网关的高可用

  • 先配置好单例的网关项目
  • 复制出另一个网关项目,把端口号加一
  • 在本地测试需要在host文件配置映射域名,如192.168.64.128 www.lagou.com😑
  • 再在Nginx的配置文件中配置反向代理
    #反向代理配置 
    #upstream中的server是真正处理请求的应用服务器地址
    upstream roger{
        #用server定义HTTP地址,注意不能使用localhost或者127.0.0.1,因为是在虚拟机上
        server 192.168.0.104:9000;#网关的ip:host
        server 192.168.0.104:9002;#网关的ip:host
    }
    server {
        listen       80;    #这里要用80
        server_name  www.lagou.com; #host文件中配置的映射域名
        location / {
            # 利用 proxy_ pass可以将请求代理到upstream命名的HTTP服务
            proxy_pass http://roger;  #转发到的地址
            index  index.html index.htm;
        }
    }

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342