springcloud 学习第二天----eureka 和 ribbon 的学习

搭建springcloud工程

子父工程的形式

架构大致如下:
子父工程的架构

mircoservice-eureka : 注册中心,提供注册服务
mircoservice-user : 用户服务,提供数据库查询服务
mircoservice-consume : 远程调用服务,提供接口查询数据

父工程 pom文件

 <modules>
        <module>mircoservice-eureka</module>
        <module>mircoservice-user</module>
        <module>mircoservice-consume</module>
   </modules>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.fangh</groupId>
    <artifactId>mircoservice</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.SR1</spring-cloud.version>
        <lombok.version>1.18.10</lombok.version>
        <mybatis-plus.version>3.2.0</mybatis-plus.version>
        <mysql-connector.version>5.1.46</mysql-connector.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-dependencies -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>${mybatis-plus.version}</version>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql-connector.version}</version>
            </dependency>

        </dependencies>

    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

子工程

eureka 注册中心
加入maven依赖
 <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>
yml 文件配置
server:
  port: 9000

eureka:
  client:
    #注册中心是否将自己注册进去
    register-with-eureka: false
    #点击进去可以看到是一个Map,key 要从类 EurekaClientConfigBean 看
    service-url:
      defaultZone: http://127.0.0.1:9000/eureka/
在application 主方法上面加上注解 @EnableEurekaServer

在主方法上面加上注解

mircoservice-user 项目
pom文件:
 <!-- web 依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- Mysql 连接池-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <!-- mybatis-plus 插件-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </dependency>

        <!--eureka 客户端-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
yml 配置文件
server:
  port: 9001

eureka:
  client:
    #点击进去可以看到是一个Map,key 要从类 EurekaClientConfigBean 看
    service-url:
      defaultZone: http://127.0.0.1:9000/eureka/
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test
    username: root
    password: root
  application:
    name: mircoservice-user
application 主方法加上注解 @EnableDiscoveryClient主方法加上注解 @EnableDiscoveryClient

为什么使用 @EnableDiscoveryClient 而不是 @EnableEurekaClient
因为**@EnableEurekaClient只是针对于eureka** 生效,其他注册中心不生效,日后将注册中心改成zookeeper 或者consul 都不会有问题

mircoservice-consume 项目工程
pom文件
 <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>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </dependency>
yml 文件
server:
  port: 9000

eureka:
  client:
    #注册中心是否将自己注册进去
    register-with-eureka: false
    #点击进去可以看到是一个Map,key 要从类 EurekaClientConfigBean 看
    service-url:
      defaultZone: http://127.0.0.1:9000/eureka/
在application 主方法上加上注解 @EnableDiscoveryClient在这里插入图片描述

为什么使用 @EnableDiscoveryClient 而不是 @EnableEurekaClient
因为**@EnableEurekaClient只是针对于eureka** 生效,其他注册中心不生效,日后将注册中心改成zookeeper 或者consul 都不会有问题

服务间的调用

昨天已经学习了服务间的调用有两种,各自的介绍也说了。
springcloud 学习第一天----微服务的介绍和了解

第一种实现(前提注入 RestTemplate bean 对象)

 String forObject = restTemplate.getForObject("http://127.0.0.1:9001/user/" + id, String.class);

直接通过 RestTemplate 调用,简单实用,但是拓展性不高,如果服务ip或者端口改变都得改变,增加日后维护的难度。

第二种实现(前提注入 RestTemplate DiscoveryClient bean对象)

//获取服务实例,可能存在多个实例,即负载均衡
List<ServiceInstance> clientInstances = discoveryClient.getInstances("mircoservice-user");
//获取其中一个实例(暂时只有一个实例对象)
ServiceInstance serviceInstance = clientInstances.get(0);
String url = "http://"+serviceInstance.getHost()+":"+serviceInstance.getPort()+"/user/" + id;
String forObject = restTemplate.getForObject(url, String.class);

通过 DiscoveryClient 对象获取服务实例对象列表,然后自己可以通过一定的算法【hash、轮询、随机等等】,获取其中一个实例进行远程服务调用。[^hash 算法]:通过将访问ip生成一个固定hash值,然后通过hash值分配一个固定访问服务。
注:暂时只取第一个服务调用

第三种实现(前提要注入 RibbonLoadBalancerClient bean 对象)

注入RibbonLoadBalancerClient
注入RibbonLoadBalancerClient
调用代码如下

ServiceInstance choose = ribbonLoadBalancerClient.choose("mircoservice-user");
String forObject = restTemplate.getForObject("http://"+choose.getHost()+":"+choose.getPort()+"/user/" + id, String.class);

第四种实现(在 RestTemplate 注入bean 增加一个 @LoadBalanced

restTemplate.getForObject("http://mircoservice-user/user/" + id, String.class);

底层实现方式

1.LoadBalancerInterceptor 拦截器实现

这种方式其实底层是通过拦截器做的,通过 LoadBalancerInterceptor 这个类 实现服务直接调用。LoadBalancerInterceptor 拦截器通过上面的类可以知道,它是通过 LoadBalancerClient 执行 execute 方法,来获取他真实的ip 地址和端口,但是他是如何实现负载均衡的呢?

2.通过LoadBalancerClient 执行 execute 方法

LoadBalancerInterceptor 执行excute 方法通过上面那个方法可以看出,是通过 ILoadBalancer 负载均衡器去获取相对应的实例,也就是说这个负载均衡器实际上会根据serviceId 会自动获取一个实例,那个实例又是怎么根据什么算法获取的呢?

3.ILoadBalancer 负载均衡器根据算法获取实例对象

获取负载均衡算法通过上面代码可知,如果负载均衡器为空,会自动获取默认的负载均衡器,那么默认的算法规则是什么呢?默认获取负载均衡器的算法规则
在这里插入图片描述通过上面代码可以知道,他默认算法规则就是 RoundRobinRule 类 ,这个类进去发现其实就是轮询,但是你看下它的源码就会发现一个问题轮询源码通过上面的代码可以知道,当负载均衡数量超过十个就会出现问题,因此,当超过十个就要重新使用其他算法来获取服务器实例。

4.配置负载均衡器算法规则

其实很简单:在yml 文件中加入配置文件
serviceId: ribbon:NFLoadBalancerRuleClassName:负载均衡算法器类全路径

mircoservice-user:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

第五种实现(前提是引用 feign 依赖)

具体请看springcloud 学习第四天----feign的学习

总结

eureka 总结

1.其实eureka 内容不多,主要是配置服务器端和客户端,但是配置客户端时记得使用 @EnableDiscoveryClient ,方便日后使用。
2.eureka 集群,通过互相注入的原则,在 defaultZone 中添加其他注册中心地址,用逗号分隔开

  client:
    #注册中心是否将自己注册进去
    register-with-eureka: false
    #点击进去可以看到是一个Map,key 要从类 EurekaClientConfigBean 看
    service-url:
      defaultZone: http://127.0.0.1:9000/eureka/,http://127.0.0.1:9090/eureka/

ribbon 总结

1.ribbon 极大的方便了我们的调用和使用,代码也简化了很多,根据serviceId 就能找到相对应的服务,还能通过相对应的算法选择一个服务进行远程调用
在这里插入图片描述在这里插入图片描述
2 其实看ribbon 的源码,极大的享受,设计算法中通过适配器来做的,根据不同的类选择不同的算法规则,以后写代码的时候可以借鉴下。
3目前负载均衡中的适配器的算法只有以下几种负载均衡算法规则

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值