zoukankan      html  css  js  c++  java
  • SpringCloud 相关

    注册中心

    Eureka

    导入依赖
    pom.xml

        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            </dependency>
        </dependencies>
    

    配置文件

    • 注册中心默认端口:8761
    server:
      port: 8761  # 默认端口
    
    eureka:
      instance:
        hostname: localhost # Eureka服务端实例名称
      client:
        registerWithEureka: false # 是否向Eureka注册自己(本身就是注册中心)
        fetchRegistry: false # false 表示自己是注册中心
        serviceUrl:
          defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ # 注册中心监控页面地址
    
    spring:
      application:
        name: eureka-server
    

    启动类

    • @EnableEurekaServer:表示为一个Eureka服务启动类
    @SpringBootApplication
    @EnableEurekaServer
    public class EurekaServerApplication {
        public static void main(String[] args) {
            new SpringApplicationBuilder(EurekaServerApplication.class).run(args);
        }
    }
    

    服务注册

    导入依赖

    <dependencies>
            <!-- eureka客户端 -->
            <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-actuator</artifactId>
            </dependency>
    
            <!-- 表示为一个web服务 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <!-- mybatis -->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>1.1.1</version>
            </dependency>
    
            <!-- mysql -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.21</version>
            </dependency>
        </dependencies>
    

    配置文件

    • instance-id:实例化id与其他服务重名时,注册中心只能找到最后一次注册
    server:
      port: 8001
    spring:
      application:
        name: product-data-service
      datasource:
        username: jerel
        password: 4464984
        url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
        driver-class-name: com.mysql.jdbc.Driver
    # 服务注册到哪里
    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:8761/eureka/ # 注册中心的地址
      instance:
        instance-id: spirngcloud-provider-user # 实例化id
    # info信息(注册中心可以获取到)
    info:
      app.name: user-service
      company.name: top.xiongyungang
    
    • 服务状态
    • 服务信息

      启动类
    • @EnableEurekaClient:在服务启动后自动注册到Eureka
    @SpringBootApplication
    @EnableEurekaClient
    public class UserServerApplication {
        public static void main(String[] args) {
            new SpringApplicationBuilder(UserServerApplication.class).run(args);
        }
    }
    

    服务保护机制

    即服务宕机不会立刻在注册中心注销该服务,可在配置中关闭这种机制

    服务调用

    负载均衡(LB)

    集中式负载均衡

    在服务的消费方和提供方之间使用独立的负载均衡设施(可以是硬件,如F5,也可以是软件,如nginx),由该设施负责吧访问请求通过某中策略转发至服务的提供方

    进程式负载均衡

    将负载均衡逻辑集成到消费方,消费方从服务注册中心获知那些地址可用,然后自己再从这些地址中选择一个合适的服务器,例如ribbon,ribbon只是一个类库,集成在消费方进程,消费方通过它来获取到服务提供方的地址

    Ribbon

    • Ribbon是Netflix下的开源项目,实现了客户端负载均衡
    • 可自定义负载均衡算法

    导入依赖

    • netflix依赖中包含Ribbon
        <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>
    

    配置

    server:
      port: 8004
    spring:
      application:
        name: ribbon-view-service
    
    # Eureka
    eureka:
      client:
        service-url:
          defaultZone: http://localhost:8761/eureka/  # 注册中心地址,多个注册中心逗号分隔
      instance:
        instance-id: springcloud--ribbon-view # 实例id
    

    配置类

    • Ribbon默认的负载均衡算法为RandomRule(轮询方式)
    @Configuration
    public class ConfigBean {
        // 配置负载均衡实现restTemplate
        @Bean
        @LoadBalanced
        public RestTemplate getRestTemplate(){
            return new RestTemplate();
        }
    
        // 自定义负载均衡算法
        @Bean
        public IRule myRule() {
            return new MyRandomRule();
            // return new RandomRule();  //默认轮询方式
        }
    
    }
    

    自定义负载均衡

    • 自定义负载均衡,实现IRole接口或继承实现了IRole接口类
    • 自定义类放在子目录中,防止被spring扫描到
        // 实现IRule
        // RandomRule: 随机策略 在while循环内,如果服务地址不为空会不停的循环直到随机出一个可用的服务
        // RoundRobinRule: 轮询策略,但是有个查找次数的限制,也就是说查了10次都是不可用的服务的话就会警告没有可用服务并返回null了,选择的方式是很简单,取余运算
        // RetryRule: 采用了轮询策略(内部直接实例化RoundRobinRule使用)的重试策略来获取可用的服务实例
        // ...
    public class MyRandomRule extends AbstractLoadBalancerRule {
        private int cnt = 0;  // 服务执行次数
        private int currIndex = 0; // 当前服务索引
    
        public MyRandomRule() {
        }
    
        public Server choose(ILoadBalancer lb, Object key) {
            if (lb == null) {
                return null;
            } else {
                Server server = null;
    
                while(server == null) {
                    if (Thread.interrupted()) {
                        return null;
                    }
    
                    List<Server> upList = lb.getReachableServers(); // 可用服务列表
                    List<Server> allList = lb.getAllServers();      // 全部服务列表
                    int serverCount = allList.size();
                    if (serverCount == 0) {
                        return null;
                    }
                    
                    // 每个服务访问两次
                    //////////////////////////
                    if (cnt < 2) {
                        cnt++;
                        server = upList.get(currIndex);
                    } else {
                        cnt = 1;
                        currIndex++;
                        if (currIndex >= upList.size()) {
                            currIndex = 0;
                        }
                        server = upList.get(currIndex);
                    }
                    ////////////////////////////
    
                    if (server == null) {
                        Thread.yield();
                    } else {
                        if (server.isAlive()) {
                            return server;
                        }
    
                        server = null;
                        Thread.yield();
                    }
                }
    
                return server;
            }
        }
    
        public Server choose(Object key) {
            return this.choose(this.getLoadBalancer(), key);
        }
    
        public void initWithNiwsConfig(IClientConfig clientConfig) {
        }
    }
    
    

    启动类

    • @RibbonClient:启动时加载自定义Ribbon客户端
    @SpringBootApplication
    @EnableEurekaClient
    @RibbonClient(name = "PRODUCT-DATA-SERVICE", configuration = MyRule.class) //启动时加载自定义Ribbon客户端
    @Controller
    public class RibbonViewApplication {
        @Autowired
        RestTemplate restTemplate; // 提供多种远程调用http服务的方式,简单的restful模板
    
        @RequestMapping("/users")
        @ResponseBody
        public List<User> listUser() {
            // 通过服务名称来访问服务
            return restTemplate.getForObject("http://PRODUCT-DATA-SERVICE/users", List.class);
        }
    
        public static void main(String[] args) {
            SpringApplication.run(RibbonViewApplication.class, args);
        }
    }
    

    Feign

    与Ribbon的不同

    • Feign基于注解和接口
    • 集成了Ribbon

    导入依赖

        <dependencies>
            <!-- eureka 客户端-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
            <!-- 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>
        </dependencies>
    

    配置

    server:
      port: 8003
    spring:
      application:
        name: view-service
    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:8761/eureka/
    

    配置Feign

    • @FeignClient:使用服务名称获取服务
    // Feign客户端,value:调用服务的注册名称
    @FeignClient(value = "PRODUCt-DATA-SERVICE")
    @Component
    public interface ViewClient {
    
        @GetMapping("/users")
        public List<User> list();
    }
    

    启动类

    • @EnableFeignClients:标记为Feign方式
    
    @SpringBootApplication
    @EnableEurekaClient
    @EnableFeignClients  // Feign方式
    @Controller
    public class ViewServiceApplication {
        public static void main(String[] args) {
            new SpringApplicationBuilder(ViewServiceApplication.class).run(args);
        }
    
        @Autowired
        ViewClient viewClient;
    
        @RequestMapping("/users")
        @ResponseBody
        public Object listUser() {
            return viewClient.list();
        }
    }
    
    

    路由网关Zuul

    功能:提供 代理+路由+过滤功能

    导入依赖

        <dependencies>
            <!-- Eureka Client-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
            <!-- web服务 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <!-- zuul -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
            </dependency>
        </dependencies>
    

    配置

    server:
      port: 9527
    spring:
      application:
        name: springcloud-zuul
    
    eureka:
      client:
        service-url:
          defaultZone: http://localhost:8761/eureka/ # 注册中心地址
      instance:
        instance-id: zuul # 实例化id
        prefer-ip-address: true # 隐藏真实ip地址
    zuul:
      routes:
        myservice1: # 自定义
          serviceId: PRODUCT-DATA-SERVICE #服务实例id,大写
          path: /data/** # 路由地址
        myservice2:
          serviceId: VIEW-SERVICE
          path: /view/**
      ignored-services: "*" # 隐藏真实项目路径,*代表全部
      prefix: /roles #设置公共路由前缀
    

    启动类

    • @EnableZuulProxy:标记为Zuul路由
    @SpringBootApplication
    @EnableZuulProxy //Zuul路由
    public class ZuulApplication {
        public static void main(String[] args) {
            SpringApplication.run(ZuulApplication.class, args);
        }
    }
    

    服务熔断Hystrix

    依赖

    <dependencies>
            <!-- Hystrix熔断服务支持-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
            </dependency>
            <!-- eureka 客户端-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
            <!-- 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>
        </dependencies>
    

    配置

    server:
      port: 8003
    spring:
      application:
        name: view-service
    feign:
      hystrix:
        enabled: true  # 开启服务熔断
    eureka:
      client:
        service-url:
          defaultZone: http://localhost:8761/eureka/ # 注册中心地址
      instance:
        instance-id: springcloud-hystrix-view # 实例化id
        prefer-ip-address: true # 隐藏真实ip地址
    

    对类的熔断

    模拟调用服务宕机

    • @FeignClient注解的fallback指定一个实现当前接口的类,在服务调用失败时,调用该类的方法实现
    // Feign客户端,value:调用服务的注册名称, fallback 熔断类
    @FeignClient(value = "PRODUCt-DATA-SERVICE", fallback = ViewHystrixClient.class)
    @Component
    public interface ViewClient {
    
        @GetMapping("/users")
        Object list();
    }
    

    熔断类

    • 实现了ViewClient接口,服务调用失败时调用该类方法实现
    // 服务熔断后的备选方案
    @Component
    public class ViewHystrixClient implements ViewClient {
    
        public Object list(){
            return "server error";
        }
    }
    
    

    启动类

    @SpringBootApplication
    @EnableEurekaClient
    @EnableFeignClients  // Feign方式
    @Controller
    public class ViewHystrixServiceApplication {
        public static void main(String[] args) {
            new SpringApplicationBuilder(ViewHystrixServiceApplication.class).run(args);
        }
    
        @Autowired
        ViewClient viewClient;
    
        @RequestMapping("/users")
        @ResponseBody
        public Object listUser() {
            return viewClient.list();
        }
    }
    

    对方法的熔断

    启动类

    • @EnableCircuitBreaker :对熔断的支持
    • @HystrixCommand(fallbackMethod = "hystrix"):当前方法执行异常时跳转到指定方法实现
    @SpringBootApplication
    @EnableEurekaClient
    @EnableFeignClients  // Feign方式
    @Controller
    @EnableCircuitBreaker // 对熔断的支持
    public class ViewHystrixServiceApplication {
        public static void main(String[] args) {
            new SpringApplicationBuilder(ViewHystrixServiceApplication.class).run(args);
        }
    
        @RequestMapping("/getUser")
        @HystrixCommand(fallbackMethod = "hystrix")
        @ResponseBody
        public Object getuser() {
            int id = 11;
            if (id > 10) {
                // 模拟故障
                throw new RuntimeException("server error");
            }
            // 使用模拟数据
            return new User(id, "testUser", "", "", "", "");
        }
    
        public Object hystrix() {
            return "server error";
        }
    }
    
    
  • 相关阅读:
    delphi 如何让ScrollBox的内容与滚动条一起实时滚动
    C# Wpf集合双向绑定
    C# Wpf异步修改UI,多线程修改UI(二)
    C# 自定义线程修改UI(一)
    WPF FindName()查找命名注册的元素
    数据绑定
    WPF绑定Binding及模式
    WPF-Binding的源
    WPF-Binding对数据的检验
    WPF-数据转换
  • 原文地址:https://www.cnblogs.com/xiongyungang/p/13943155.html
Copyright © 2011-2022 走看看