• SpringCloud入门


    SpringCloud

    1、springcloud概述

    SpringCloud是一种微服务架构,依赖于SpringBoot,主要用于服务治理(解耦),其中每一个服务都可以独立运行,服务之间没有依懒关系

    2、Eureka注册中心搭建

    1、pom.xml配置

    <parent>

          <groupId>org.springframework.boot</groupId>

          <artifactId>spring-boot-starter-parent</artifactId>

          <version>1.5.2.RELEASE</version>

          <relativePath />

       </parent>

      

       <properties>

          <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

       <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

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

       </properties>

      

       <dependencies>

          <dependency>

            <groupId>org.springframework.cloud</groupId>

            <artifactId>spring-cloud-starter</artifactId>

          </dependency>

          <dependency>

            <groupId>org.springframework.cloud</groupId>

            <artifactId>spring-cloud-starter-eureka-server</artifactId>

          </dependency>

          <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-test</artifactId>

            <scope>test</scope>

          </dependency>

       </dependencies>

      

       <dependencyManagement>

          <dependencies>

            <dependency>

               <groupId>org.springframework.cloud</groupId>

               <artifactId>spring-cloud-dependencies</artifactId>

               <version>Dalston.RC1</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>

       <repositories>

          <repository>

            <id>spring-milestones</id>

            <name>Spring Milestones</name>

            <url>https://repo.spring.io/milestone</url>

            <snapshots>

               <enabled>false</enabled>

            </snapshots>

          </repository>

       </repositories>

    2、application.properties配置

    spring.application.name=spring-cloud-eureka

    server.port=8000

    eureka.client.register-with-eureka=false

    eureka.client.fetch-registry=false

    eureka.client.serviceUrl.defaultZone=http://localhost:${server.port}/eureka/

    eureka.client.register-with-eureka :表示是否将自己注册到Eureka Server,默认为true。

    eureka.client.fetch-registry :表示是否从Eureka Server获取注册信息,默认为true。

    eureka.client.serviceUrl.defaultZone :服务注册中心的配置内容,指定服务注册中心的位置。默认是http://localhost:8761/eureka ;多个地址可使用 , 分隔。

    注:Eureka的yml配置文件中冒号后必须有空格,不能是’ ’;

    3、服务启动

    @SpringBootApplication

    @EnableEurekaServer

    public class EurekaApp {

       public static void main(String[] args) {

          SpringApplication.run(EurekaApp.class, args);

       }

    }

    @EnableEurekaServer启动一个服务注册中心提供给其他服务进行注册

    @SpringBootApplication:扫描当前包及其子包下的带有@Component,@Controller,@Service,@Repository注解的类,并纳入spring容器进行管理配置

    4、Eureka集群

    1、application.properties配置

    application.properties:

    spring:

      application:

        name: spring-cloud-eureka

      profiles:

       active: peer1

    application-peer1.properties:

    spring.profiles=peer1

    server.port=8000

    eureka.client.serviceUrl.defaultZone=http://peer2:8001/eureka/, http://peer3:8002/eureka/

    application-peer2.properties:

    spring.profiles=peer2

    server.port=8001

    eureka.client.serviceUrl.defaultZone=http://peer1:8000/eureka/, http://peer3:8002/eureka/

    application-peer3.properties:

    spring.profiles=peer3

    server.port=8002

    eureka.client.serviceUrl.defaultZone=http://peer1:8000/eureka/, http://peer2:8001/eureka/

    2、在C:WindowsSystem32driversetc下的hosts文件中加入

    127.0.0.1  peer1

    127.0.0.1  peer2

    127.0.0.1  peer3

    3、打包

    --->maven build …--->clean package

    4、依次启动

    java -jar E:javaspring-cloud-eureka argetspring-cloud-eureka-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer1

    java -jar E:javaspring-cloud-eureka argetspring-cloud-eureka-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer2

    java -jar E:javaspring-cloud-eureka argetspring-cloud-eureka-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer3

    3、服务提供者

    1、pom.xml配置

    <parent>

          <groupId>org.springframework.boot</groupId>

          <artifactId>spring-boot-starter-parent</artifactId>

          <version>1.5.2.RELEASE</version>

          <relativePath />

       </parent>

       <properties>

          <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

       <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

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

       </properties>

       <dependencies>

          <dependency>

            <groupId>org.springframework.cloud</groupId>

            <artifactId>spring-cloud-starter-eureka</artifactId>

          </dependency>

          <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-test</artifactId>

            <scope>test</scope>

          </dependency>

       </dependencies>

       <dependencyManagement>

          <dependencies>

            <dependency>

               <groupId>org.springframework.cloud</groupId>

               <artifactId>spring-cloud-dependencies</artifactId>

               <version>Dalston.RC1</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>

       <repositories>

          <repository>

            <id>spring-milestones</id>

            <name>Spring Milestones</name>

            <url>https://repo.spring.io/milestone</url>

            <snapshots>

               <enabled>false</enabled>

            </snapshots>

          </repository>

       </repositories>

    2、application.properties配置

    spring.application.name=spring-cloud-provider

    server.port=9000

    eureka.client.serviceUrl.defaultZone=http://localhost:8000/eureka/

    3、服务启动

    @SpringBootApplication

    @EnableEurekaClient

    public class ProviderApp {

       public static void main(String[] args) {

          SpringApplication.run(ProviderApp.class, args);

       }

    }

    @EnableDiscoveryClient启用服务注册与发现

    @EnableEurekaClient启用服务注册与发现

    4、controller

    @RestController

    public class ProviderController {

       @RequestMapping("/provider")

        public String proindex(@RequestParam String name) {

            return "hello "+name+",this is first provider messge";

        }

    }

    4、服务消费者

    1、pom.xml配置

    <parent>

          <groupId>org.springframework.boot</groupId>

          <artifactId>spring-boot-starter-parent</artifactId>

          <version>1.5.2.RELEASE</version>

          <relativePath />

       </parent>

       <properties>

          <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

       <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

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

       </properties>

       <dependencies>

          <dependency>

            <groupId>org.springframework.cloud</groupId>

            <artifactId>spring-cloud-starter-eureka</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-feign</artifactId>

          </dependency>

          <dependency>

            <groupId>org.springframework.cloud</groupId>

            <artifactId>spring-cloud-starter-hystrix</artifactId>

          </dependency>

          <dependency>

            <groupId>org.springframework.cloud</groupId>

            <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>

          </dependency>

          <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-actuator</artifactId>

          </dependency>

       </dependencies>

       <dependencyManagement>

          <dependencies>

            <dependency>

               <groupId>org.springframework.cloud</groupId>

               <artifactId>spring-cloud-dependencies</artifactId>

               <version>Dalston.RC1</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>

       <repositories>

          <repository>

            <id>spring-milestones</id>

            <name>Spring Milestones</name>

            <url>https://repo.spring.io/milestone</url>

            <snapshots>

               <enabled>false</enabled>

            </snapshots>

          </repository>

       </repositories>

    2、application.properties配置

    spring.application.name=spring-cloud-consumer

    server.port=9100

    eureka.client.serviceUrl.defaultZone=http://localhost:8000/eureka/

    3、服务启动

    1、rest启动

    @SpringBootApplication

    @EnableEurekaClient

    public class ConsumerApp {

       public static void main(String[] args) {

          SpringApplication.run(ConsumerApp.class, args);

       }

    }

    2、feign启动

    @SpringBootApplication

    @EnableEurekaClient

    @EnableFeignClients

    public class Consumer1App {

       public static void main(String[] args) {

          SpringApplication.run(Consumer1App.class, args);

       }

    }

    @EnableFeignClients启用feign进行远程调用

    4、rest调用

    1、controller

    @RestController

    public class ConsumerController {

       @Autowired

       private ConsumerService cs;

       @RequestMapping("/consumer")

        public String conindex() {

          return cs.getConsumer();

        }

    }

    2、service

    @Service

    public class ConsumerService {

       @Autowired

       private RestTemplate rt;

     

       public String getConsumer() {

          return rt.getForObject("http://spring-cloud-provider/provider",String.class);

       }

    }

    5、feign调用

    1、controller

    @RestController

    public class Consumer1Controller {

       @Autowired

       HelloRemote helloRemote;

       @RequestMapping("/consumer1/{name}")

       public String index(@PathVariable("name") String name) {

          return helloRemote.index(name);

       }

    }

    2、service

    @FeignClient(name="spring-cloud-provider1")

    public interface HelloRemote {

       @RequestMapping("/provider1")

        public String index(@RequestParam(value = "name") String name);

    }

    @FeignClient指定要绑定的远程调用的服务,参数为服务的名字

    @RequestMapping为调用的提供者方法的映射名

    SpringMVC@RequestParam@RequestHeader注解,如果我们不指定value,则默认采用参数的名字作为其value,但是在Feign中,这个value必须明确指定,否则会报错。

    5、hystrix

    1、配置文件

    feign.hystrix.enabled=true

    2、客户端调用

    @FeignClient(name="spring-cloud-provider",fallback=FallbackRemote.class)

    public interface HelloRemote {

       @RequestMapping(value = "/hello1", method = RequestMethod.GET)

       String hello(@RequestParam("name") String name);

       @RequestMapping(value = "/hello2", method = RequestMethod.GET)

       User hello(@RequestHeader("name") String name, @RequestHeader("age") Integer age);

       @RequestMapping(value = "/hello3", method = RequestMethod.POST)

       String hello(@RequestBody User user);

    }

    3、启动类

    @EnableCircuitBreaker

    @EnableHystrixDashboard(开启监控)

    6、zuul网关

    1、pom文件配置

    <dependency>

        <groupId>org.springframework.cloud</groupId>

        <artifactId>spring-cloud-starter-zuul</artifactId>

    </dependency>

    2、配置

    eureka:

      client:

        serviceUrl:

          defaultZone: http://localhost:8000/eureka/

    server:

      port: 9400

    spring:

      application:

        name: zuul

    zuul:

      routes:

        api-a:

          path: /provider/**

          service-id: spring-cloud-provider

        api-b:

          path: /consumer/**

          service-id: spring-cloud-consumer

    1、zuul默认配置

    spring cloud zuul已经帮我们做了默认配置。默认情况下,Zuul会代理所有注册到Eureka Server的微服务,并且Zuul的路由规则如下:

    http://ZUUL_HOST:ZUUL_PORT/微服务在Eureka上的serviceId/**

    会被转发到serviceId对应的微服务

    2、zuul熔断

    Zuul 目前只支持服务级别的熔断,不支持具体到某个URL进行熔断。

    3、启动类

    @EnableZuulProxy

    @EnableEurekaClient

    @SpringBootApplication

    public class AppZull {

        public static void main(String[] args) {

          SpringApplication.run(AppZull.class, args);

       }

    }

    4、zuul负载均衡

    Zuul负载均衡是属于客户端的负载均衡

    客户端负载均衡:

    基于客户端的负载均衡,简单的说就是在客户端程序里面,自己设定一个调度算法,在向服务器发起请求的时候,先执行调度算法计算出向哪台服务器发起请求,然后再发起请求给服务器。

    特点:

    1. 由客户端内部程序实现,不需要额外的负载均衡器软硬件投入。
    2. 程序内部需要解决业务服务器不可用的问题,服务器故障对应用程序的透明度小。
    3. 程序内部需要解决业务服务器压力过载的问题。

    使用场景:

    1. 可以选择为初期简单的负载均衡方案,和DNS负载均衡一样。
    2. 比较适合于客户端具有成熟的调度库函数,算法以及API等
    3. 比较适合对服务器入流量较大的业务,如HTTP POST文件上传,FTP文件上传,Memcache大流量写入。
    4. 可以结合其他负载均衡方案进行架构。

    5、Zuul的核心Filter

    1、概述

    Filter是Zuul的核心,用来实现对外服务的控制。Filter的生命周期有4个,分别是“PRE”、“ROUTING”、“POST”、“ERROR”;

    Zuul大部分功能都是通过过滤器来实现的,这些过滤器类型对应于请求的典型生命周期。

    • PRE 这种过滤器在请求被路由之前调用。我们可利用这种过滤器实现身份验证、在集群中选择请求的微服务、记录调试信息等。
    • ROUTING这种过滤器将请求路由到微服务。这种过滤器用于构建发送给微服务的请求,并使用Apache HttpClient或Netfilx Ribbon请求微服务。
    • POST这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等。
    • ERROR在其他阶段发生错误时执行该过滤器。
      除了默认的过滤器类型,Zuul还允许我们创建自定义的过滤器类型。例如,我们可以定制一种STATIC类型的过滤器,直接在Zuul中生成响应,而不将请求转发到后端的微服务。

    2、Zuul中默认实现的Filter

    类型     顺序     过滤器                               功能

    pre             -3         ServletDetectionFilter             标记处理Servlet的类型

    pre             -2         Servlet30WrapperFilter          包装HttpServletRequest请求

    pre             -1         FormBodyWrapperFilter        包装请求体

    route 1          DebugFilter                          标记调试标志

    route 5          PreDecorationFilter          处理请求上下文供后续使用

    route 10               RibbonRoutingFilter          serviceId请求转发

    route 100     SimpleHostRoutingFilter url    请求转发

    route 500     SendForwardFilter                   forward请求转发

    post     0          SendErrorFilter                   处理有错误的请求响应

    post     1000   SendResponseFilter           处理正常的请求响应

    3、禁用指定的Filter

    zuul:

        FormBodyWrapperFilter:

            pre:

                disable: true

    4、自定义Filter

    public class MyFilter extends ZuulFilter {

        @Override

        String filterType() {

            return "pre"; //定义filter的类型,有pre、route、post、error四种

        }

        @Override

        int filterOrder() {

            return 10; //定义filter的顺序,数字越小表示顺序越高,越先执行

        }

        @Override

        boolean shouldFilter() {

            return true; //表示是否需要执行该filter,true表示执行,false表示不执行

        }

        @Override

    Object run() {

    return null; //filter需要执行的具体操作

    /*

    RequestContext ctx = RequestContext.getCurrentContext();

                  HttpServletRequest request = ctx.getRequest();

                  log.info(String.format("%s >>> %s", request.getMethod(), request.getRequestURL().toString()));

                  Object accessToken = request.getParameter("token");

                  String refer=request.getHeader("refer");

          

                  if (accessToken != null) {

                         return null;

                  }

                  log.warn("token is empty");

                  ctx.setSendZuulResponse(false);

                  ctx.setResponseStatusCode(401);

                  try {

                         ctx.getResponse().getWriter().write("token is empty");

                  } catch (Exception e) {

                  }

                  return null;

    */

        }

    }

    5、将TokenFilter加入到请求拦截队列,在启动类中添加代码:

    @Bean

    public TokenFilter tokenFilter() {

        return new TokenFilter();

    }

    7、config配置中心

    1、config-server搭建

    1、pom依赖

    <dependency>

            <groupId>org.springframework.cloud</groupId>

       <artifactId>spring-cloud-config-server</artifactId>

    </dependency>

    2、配置

    spring.application.name=config-server

    server.port=9200

    spring.cloud.config.server.git.uri=https://gitee.com/archimedes123/config.git

    spring.cloud.config.server.git.username=

    spring.cloud.config.server.git.password=

    eureka.client.serviceUrl.defaultZone=http://localhost:8000/eureka/

    假设远程配置文件名为config-dev.properties

    内容为:hellohello im dev

    它的applicationconfigprofiledev。client会根据填写的参数来选择读取对应的配置。

    仓库中的配置文件会被转换成web接口,访问可以参照以下的规则:

    1/{application}/{profile}[/{label}]

    2/{application}-{profile}.*

    3/{label}/{application}-{profile}.*

    3、启动类

    @SpringBootApplication

    @EnableConfigServer

    @EnableEurekaClient

    public class ConfigServerApp {

       public static void main(String[] args) {

          SpringApplication.run(ConfigServerApp.class, args);

       }

    }

    4、webhook机制检测更新配置(需要消息中间件支持rabbitMQ)

    1、pom依赖

    <dependency>

           <groupId>org.springframework.cloud</groupId>

           <artifactId>spring-cloud-starter-bus-amqp</artifactId>

    </dependency>

    2、配置文件

    server:

      port: 8001

    spring:

      application:

        name: spring-cloud-config-server

      cloud:

        config:

          server:

            git:

              uri: https://github.com/ityouknow/spring-cloud-starter/    

    # 配置git仓库的地址

              search-paths: config-repo                            

    # git仓库地址下的相对地址,可以配置多个,用,分割。

              username: username                                       

    # git仓库的账号

              password: password                                  

     # git仓库的密码

      rabbitmq:

        host: 192.168.0.6

        port: 5672

        username: admin

        password: 123456

    eureka:

      client:

        serviceUrl:

          defaultZone: http://localhost:8000/eureka/   ## 注册中心eurka地址

    management:

      security:

         enabled: false

    2config-client搭建

    1、pom依赖

    <dependency>

            <groupId>org.springframework.cloud</groupId>

            <artifactId>spring-cloud-starter-config</artifactId>

    </dependency>

    <dependency>

            <groupId>org.springframework.cloud</groupId>

       <artifactId>spring-cloud-starter-eureka</artifactId>

    </dependency>

    <dependency>

            <groupId>org.springframework.boot</groupId>

          <artifactId>spring-boot-starter-web</artifactId>

    </dependency>

    <dependency>

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

            <scope>test</scope>

    </dependency>

    2、bootstrap.properties配置

    spring.application.name=config-client

    spring.cloud.config.name=config

    spring.cloud.config.profile=dev

    spring.cloud.config.label=master

    server.port=9300

    eureka.client.serviceUrl.defaultZone=http://localhost:8000/eureka/

    spring.cloud.config.discovery.enabled=true

    spring.cloud.config.discovery.serviceId=config-server

    • ·         spring.cloud.config.name:对应{application}部分
    • ·         spring.cloud.config.profile:对应{profile}部分
    • ·         spring.cloud.config.label:对应git的分支。如果配置中心使用的是本地存储,则该参数无用
    • ·         spring.cloud.config.uri:配置中心的具体地址
    • ·         spring.cloud.config.discovery.service-id:指定配置中心的service-id,便于扩展为高可用配置集群。

    特别注意:上面这些与spring-cloud相关的属性必须配置在bootstrap.properties中,config部分内容才能被正确加载。因为config的相关配置会先于application.properties,而bootstrap.properties的加载也是先于application.properties

    @RefreshScope:使用该注解的类,会在接到SpringCloud配置中心配置刷新的时候,自动将新的配置更新到该类对应的字段中。

    3、启动类

    @SpringBootApplication

    @EnableEurekaClient

    public class ConfigClientApp {

       public static void main(String[] args) {

          SpringApplication.run(ConfigClientApp.class, args);

       }

    }

    4、controller

    @RestController

    @RefreshScope//客户端启动配置中心自动更新

    public class TestController {

       @Value("${hello}")

       private String hello;

       @RequestMapping("/getHello")

       public String getHello() {

          return this.hello;

       }

    }

    8、springcloud负载均衡

    zuul也有负载均衡的功能,它是针对外部请求做负载,那客户端ribbon的负载均衡又是怎么一回事?

    客户端ribbon的负载均衡,解决的是服务发起方(在Eureka注册的服务)对被调用的服务的负载,比如我们查询商品服务要调用显示库存和商品明细服务,通过商品服务的接口将两个服务组合,可以减少外部应用的请求,比如手机App发起一次请求即可,可以节省网络带宽,也更省电。

    ribbon是对服务之间调用做负载,是服务之间的负载均衡,zuul是可以对外部请求做负载均衡。 

    1、负载均衡策略设置

    1、rabbion配置文件

    service-B.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule

    其中service-B是我注册到Eureka的serviceID。

    2、启动类

    @Bean

    public IRule ribbonRule() {

           return new RandomRule();//这里配置策略,和配置文件对应

    }

    3、controller

    @RestController

    public class ConsumerController {

        @Autowired

        private RestTemplate restTemplate;

        @Autowired 

        private LoadBalancerClient loadBalancerClient; 

        @RequestMapping(value = "/add", method = RequestMethod.GET)

        public String add(@RequestParam Integer a,@RequestParam Integer b) {

            this.loadBalancerClient.choose("service-B");//负载均衡策略

            return restTemplate.getForEntity("http://service-B/add?a="+a+"&b="+b, String.class).getBody();

        }

    }

    9、springcloud注解

    1、@EnableEurekaServer:

    启动一个服务注册中心提供给其他应用进行对话

    2、@EnableZuulProxy:

    开启网关;

    3、@FeignClient:

    发现服务

    4@EnableFeignClients

    启用feign进行远程调用

    5@EnableCircuitBreaker:

    启动断路器

    6、@EnableDiscoveryClient:

    启用服务注册与发现

    7、@EnableEurekaClient:

    启用服务注册与发现

    @EnableDiscoveryClient基于spring-cloud-commons; @EnableEurekaClient基于spring-cloud-netflix;其实用更简单的话来说,就是如果选用的注册中心是eureka,那么就推荐@EnableEurekaClient,如果是其他的注册中心,那么推荐使用@EnableDiscoveryClient。

  • 相关阅读:
    Vue学习手记01-安装和项目创建
    [Powershell] FTP Download File
    [PowerShell] Backup Folder and Files Across Network
    SSRS 请求并显示SharePoint人员和组字段
    Beta 冲刺 (2/7)
    Beta 冲刺 (1/7)
    BETA 版冲刺前准备
    事后诸葛亮
    Alpha 答辩总结
    α冲刺 (10/10)
  • 原文地址:https://www.cnblogs.com/archimedes-euler/p/9975633.html
Copyright © 2020-2023  润新知