zoukankan      html  css  js  c++  java
  • SpringCloud基础

    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: xxxxxxx@qq.com
              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: 821578297@qq.com
              password: wl802085
      rabbitmq:
        host: 172.16.10.221
    management:
      endpoints:
        web:
          exposure:
            include: bus-refresh

    被调的服务配置文件

    server:
      port: 9001
    spring:
      application:
        name: base
      rabbitmq:
        host: 172.16.10.221
    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

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

  • 相关阅读:
    作业十二 字符串和结构
    作业十一 指针(2)
    作业十 指针(1)
    作业九 二维数组和字符数组的应用
    作业八 一堆数组的应用
    作业七 函数及数组
    作业六 函数
    作业五 循环结构
    作业四 分支结构
    作业12总结
  • 原文地址:https://www.cnblogs.com/anni-qianqian/p/12017963.html
Copyright © 2011-2022 走看看