SpringCloud基础+基本框架

  • 2019 年 12 月 27 日
  • 筆記

SpringCloud极大的简化了分布式系统的开发,实现了微服务的快速部署和灵活应用

SpringCloud主要框架

* 服务发现–Netfix Eureka

* 服务调用–Netfix Feign

* 熔断器–Netfix Hystrix

* 服务网关–Netfix Zuul

* 分布式配置–Spring Cloud Config

* 消息总线–Spring Cloud Bus

注意SpringCloud和SpringBoot版本要一一对应,不然会报错

一。Eureka服务发现

外部的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>      <packaging>pom</packaging>      <modules>          <module>tensquare_eureka</module>      </modules>        <parent>          <groupId>org.springframework.boot</groupId>          <artifactId>spring-boot-starter-parent</artifactId>          <version>2.0.3.RELEASE</version>      </parent>        <groupId>com.jinke</groupId>      <artifactId>springboot</artifactId>      <version>1.0-SNAPSHOT</version>        <dependencyManagement>          <dependencies>              <dependency>                  <groupId>org.springframework.cloud</groupId>                  <artifactId>spring-cloud-dependencies</artifactId>                  <version>Finchley.RELEASE</version>                  <type>pom</type>                  <scope>import</scope>              </dependency>          </dependencies>      </dependencyManagement>      <dependencies>          <dependency>              <groupId>org.springframework.boot</groupId>              <artifactId>spring-boot-starter-web</artifactId>              <version>2.0.3.RELEASE</version>          </dependency>            <dependency>              <groupId>org.springframework.boot</groupId>              <artifactId>spring-boot-devtools</artifactId>          </dependency>      </dependencies>    </project>

内部的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">      <parent>          <artifactId>springboot</artifactId>          <groupId>com.jinke</groupId>          <version>1.0-SNAPSHOT</version>      </parent>      <modelVersion>4.0.0</modelVersion>        <artifactId>tensquare_eureka</artifactId>        <dependencies>          <dependency>              <groupId>org.springframework.cloud</groupId>              <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>              <version>2.1.2.RELEASE</version>          </dependency>      </dependencies>    </project>

application.yml

server:    port: 6868  eureka:    client:      register-with-eureka: false      fetch-registery: false      service-url:        defaultZone: http://127.0.0.1:${server.port}/eureka/

EurekaServer.java

package com.tensquare.eureka;    import org.springframework.boot.SpringApplication;  import org.springframework.boot.autoconfigure.SpringBootApplication;  import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;    @SpringBootApplication  @EnableEurekaServer  public class EurekaServer {      public static void main(String[] args) {          SpringApplication.run(EurekaServer.class);      }  }

直接启动看

二。Eureka服务注册

新建一个module

在pom.xml中增加

<dependency>      <groupId>org.springframework.cloud</groupId>      <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>      <version>2.1.2.RELEASE</version>  </dependency>

application.yml

server:    port: 9004  spring:    application:      name: register  eureka:    client:      service-url:        defaultZone: http://127.0.0.1:6868/eureka/    instance:      prefer-ip-address: true

RegisterApplication.java

package com.example.register;    import org.springframework.boot.SpringApplication;  import org.springframework.boot.autoconfigure.SpringBootApplication;  import org.springframework.cloud.netflix.eureka.EnableEurekaClient;    @SpringBootApplication  @EnableEurekaClient  public class RegisterApplication {        public static void main(String[] args) {          SpringApplication.run(RegisterApplication.class, args);      }    }

applicaiton跑起来,看结果已经注册成功了

三。服务调用

被调register的LabelController

package com.example.register.controller;    import org.springframework.web.bind.annotation.*;    @RestController  @RequestMapping("/label")  @CrossOrigin  public class LabelController {        @RequestMapping(value = "/{labelId}", method = RequestMethod.GET)      public String findById(@PathVariable("labelId") String id) {          System.out.println("调用成功");          return "success";      }    }

主调register2的ProblerController

package com.example.register2.controller;    import com.example.register2.client.BaseClient;  import org.springframework.beans.factory.annotation.Autowired;  import org.springframework.web.bind.annotation.*;    @RestController  @CrossOrigin  @RequestMapping("/problem")  public class ProblemController {      @Autowired      private BaseClient baseClient;        @RequestMapping(value = "/label/{labelId}", method = RequestMethod.GET)      public String findByLabelId(@PathVariable String labelId) {          baseClient.findById(labelId);          return "success";      }  }

application

package com.example.register2;    import org.springframework.boot.SpringApplication;  import org.springframework.boot.autoconfigure.SpringBootApplication;  import org.springframework.cloud.client.discovery.EnableDiscoveryClient;  import org.springframework.cloud.netflix.eureka.EnableEurekaClient;  import org.springframework.cloud.openfeign.EnableFeignClients;    @SpringBootApplication  @EnableEurekaClient  @EnableDiscoveryClient  @EnableFeignClients  public class Register2Application {        public static void main(String[] args) {          SpringApplication.run(Register2Application.class, args);      }    }

BaseClient

package com.example.register2.client;    import org.springframework.cloud.openfeign.FeignClient;  import org.springframework.web.bind.annotation.PathVariable;  import org.springframework.web.bind.annotation.RequestMapping;  import org.springframework.web.bind.annotation.RequestMethod;    @FeignClient("register")  public interface BaseClient {        @RequestMapping(value = "/label/{labelId}", method = RequestMethod.GET)      public String findById(@PathVariable("labelId") String labelId);  }

eureka和register、register2服务都分别跑起来

同时可以看到register的控制台输出了“调用成功”,即代表调用其他服务成功

Spring已经实现了负载均衡,即调用服务集群时,会公平的轮流调用其中的服务

四。熔断器

熔断器可以有效避免雪崩现象

当被调服务挂掉以后,会走熔断器里面的内容

调用的服务增加实现类

package com.example.register2.client.impl;    import com.example.register2.client.BaseClient;  import org.springframework.stereotype.Component;    @Component  public class BaseClientImpl implements BaseClient {      @Override      public String findById(String labelId) {          System.out.println("熔断器触发了");          return "success";      }  }

application.yml增加

feign:    hystrix:      enabled: true

五。网关

网关的作用就相当于一个中转分发站,接口

新建一个网关

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">      <parent>          <artifactId>springboot</artifactId>          <groupId>com.jinke</groupId>          <version>1.0-SNAPSHOT</version>      </parent>      <modelVersion>4.0.0</modelVersion>        <artifactId>manager</artifactId>        <dependencies>          <dependency>              <groupId>org.springframework.cloud</groupId>              <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>              <version>2.1.2.RELEASE</version>          </dependency>          <dependency>              <groupId>org.springframework.cloud</groupId>              <artifactId>spring-cloud-starter-netflix-zuul</artifactId>              <version>2.1.2.RELEASE</version>          </dependency>      </dependencies>    </project>

application.yml

server:    port: 9011  spring:    application:      name: manager  eureka:    client:      service-url:        defaultZone: http://127.0.0.1:6868/eureka/    instance:      prefer-ip-address: true  zuul:    routes:      register:        path: /register/**        serviceId: register

application

package com.jinke.manager;    import org.springframework.boot.SpringApplication;  import org.springframework.boot.autoconfigure.SpringBootApplication;  import org.springframework.cloud.netflix.eureka.EnableEurekaClient;  import org.springframework.cloud.netflix.zuul.EnableZuulProxy;    @SpringBootApplication  @EnableEurekaClient  @EnableZuulProxy  public class ManagerApplication {      public static void main(String[] args) {          SpringApplication.run(ManagerApplication.class);      }  }

然后启动服务即可

六。网关过滤

在网关模块新建一个过滤类即可

package com.jinke.manager.filter;    import com.netflix.zuul.ZuulFilter;  import com.netflix.zuul.exception.ZuulException;  import org.springframework.stereotype.Component;    @Component  public class ManagerFilter extends ZuulFilter {      @Override      public String filterType() {          //过滤器类型:之前或之后          return "pre";      }        @Override      public int filterOrder() {          //多个过滤器的执行顺序          return 0;      }        @Override      public boolean shouldFilter() {          //是否开启该过滤器          return true;      }        @Override      public Object run() throws ZuulException {          //如果设置setsendzullResponse(false)表示不再继续执行          System.out.println("已经执行到最后了");          return null;      }  }

七。SpringCloudConfig配置

新建config的module

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">      <parent>          <artifactId>springboot</artifactId>          <groupId>com.jinke</groupId>          <version>1.0-SNAPSHOT</version>      </parent>      <modelVersion>4.0.0</modelVersion>        <artifactId>config</artifactId>      <dependencies>          <dependency>              <groupId>org.springframework.cloud</groupId>              <artifactId>spring-cloud-config-server</artifactId>              <version>2.1.3.RELEASE</version>          </dependency>      </dependencies>  </project>

application.xml

server:    port: 12000  spring:    application:      name: config    cloud:      config:        server:          git:            uri: https://gitee.com/king1039/springcloud-config.git            username: [email protected]            password: xxxxxx

application

package com.jinke.config;    import org.springframework.boot.SpringApplication;  import org.springframework.boot.autoconfigure.SpringBootApplication;  import org.springframework.cloud.config.server.EnableConfigServer;    @SpringBootApplication  @EnableConfigServer  public class ConfigApplication {      public static void main(String[] args) {          SpringApplication.run(ConfigApplication.class);      }  }

服务跑起来,如果提示Authentication is required but no CredentialsProvider has been registered是因为要账号密码验证,在配置文件填上

在git上修改以后,刷新会得到新的结果

下面通过配置来调用服务

新建一个base的module

bootstrap.myl

spring:    cloud:      config:        name: springcloud        profile: config        label: master        uri: http://127.0.0.1:12000

git上的配置文件springcloud-config.yml

server:    port: 9001  spring:    application:      name: base  eureka:    client:      service-url:          defaultZone: http://127.0.0.1:6868/eureka/    instance:      prefer-ip-address: true

开启eureka、config、base三个服务,然后调用

流程就是先读取Git上的配置,然后拉下来,再调用服务

下面来通过bus消息开启监听

config的配置文件application.yml

server:    port: 12000  spring:    application:      name: config    cloud:      config:        server:          git:            uri: https://gitee.com/king1039/springcloud-config.git            username: ********@qq.com            password: ******    rabbitmq:      host: ***.***.***.***  management:    endpoints:      web:        exposure:          include: bus-refresh

被调的服务配置文件

server:    port: 9001  spring:    application:      name: base    rabbitmq:      host: ***.***.***.***  eureka:    client:      service-url:          defaultZone: http://127.0.0.1:6868/eureka/    instance:      prefer-ip-address: true

修改了被调配置文件后,使用post请求发送一次bus-refresh即可实现消息传递

如果要监听自定义的标签需要增加注解@RefreshScope

代码地址:https://github.com/king1039/SpringCloud.git

欢迎关注我的微信公众号:安卓圈