SpringCloud学习笔记

该笔记简化并省略了一些官方介绍,使用比价通俗的白话进行讲述,如果有什么需要详细了解的请自行查询资料学习

1. SpringCloud简介

SpringCloud主要功能在于服务间调用,服务可以分为提供者和消费者,提供者来提供数据,消费者来使用数据。

基于restTemplate进行服务间调用。

2. 创建项目

创建maven项目,pom.xml中添加以下配置

<properties>
    <maven.compiler.source>8</maven.compiler.source>
    <maven.compiler.target>8</maven.compiler.target>
    <mysql.version>5.1.47</mysql.version>
    <druid.version>1.1.21</druid.version>
    <mybatis.version>1.3.2</mybatis.version>
    <lombok.version>1.18.16</lombok.version>
    <logback.version>1.2.3</logback.version>
</properties>

<dependencyManagement>
    <dependencies>
        <!-- SpringCloud依赖 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Hoxton.SR9</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <!-- SpringBoot依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.2.6.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <!-- mysql数据库依赖 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.version}</version>
        </dependency>
        <!-- 阿里数据源依赖 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>${druid.version}</version>
        </dependency>
        <!-- mybatis -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>${mybatis.version}</version>
        </dependency>
        <!-- lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
        </dependency>
        <!-- logback -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>${logback.version}</version>
        </dependency>
    </dependencies>
</dependencyManagement>

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

到此我们已经为SpringCloud项目搭建了一个地基。

此时,我们可以删除掉项目下的src目录,因为我们现在创建的仅仅是一个父级项目而已。

3. Eureka注册中心

为了使服务间调用更加便捷,延伸出了注册中心,Eureka就是一种注册中心,你所启动的服务需要注册到注册中心上才能够被其他服务所发现。也就是说一个服务调用另一个服务首先去注册中心查询要调用的服务信息(打个比方就是查电话本),通过查到的信息再请求对应的地址(打个比方就是查到了电话号码了要拨打对应人的手机号)。

Eureka基于Rest,用于定位服务。

通过Eureka可以监控所有服务,来查看服务是否正常运行。

创建Eureka注册中心

我们在父级项目中创建一个Module,然后添加以下依赖

<!-- SpringCloud的Eureka依赖 -->
<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka-server</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>
</dependencies>

然后在resource中创建application.yml配置文件,添加以下配置

server:
  ## 配置端口号
  port: 9001

eureka:
  instance:
    ## 注册中心的hostname
    hostname: localhost
  client:
    ## 是否向注册中心注册自己
    register-with-eureka: false
    ## false时表示当前服务为注册中心
    fetch-registry: false
    service-url:
      ## 注册中心位置
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

创建启动类,添加如下代码

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer
public class FneeEurekaApplication {

    public static void main(String[] args) {
        SpringApplication.run(FneeEurekaApplication.class);
    }
}

现在你可以尝试启动以下该项目,访问localhost:9001就可以看到项目的注册中心页面了,如下

在这里插入图片描述

注册测试

现在你可以在项目中再创建一个Module,添加如下依赖

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka</artifactId>
        <version>1.4.7.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

配置文件添加如下配置

server:
  port: 8081
spring:
  application:
    ## application名称
    name: provider
eureka:
  client:
    service-url:
      ## eureka注册地址
      defaultZone: http://localhost:9001/eureka/
  instance:
    ## 定义注册中心页面实例的status值
    instance-id: springCloud-provider-8081

启动项目后会发现,在注册中心页面多了一个Application

在这里插入图片描述

集群

eureka集群可以避免当注册中心down掉时影响网站的正常运行。

创建多个eureka注册中心,可以放到不同的服务器进行进行通信,通过注册中心的互相绑定来达到集群的目的。

在eureka注册中心中的配置文件中配置defaultZone来绑定其他注册中心,多个注册中心可以通过英文逗号间隔。

如当前有http://testEureka001.com/eurekahttp://testEureka002.com/eurekahttp://testEureka003.com/eureka三个注册中心,可以如下配置

注册中心defaultZone
http://testEureka001.com/eurekahttp://testEureka002.com/eureka,http://testEureka003.com/eureka
http://testEureka002.com/eurekahttp://testEureka001.com/eureka,http://testEureka003.com/eureka
http://testEureka003.com/eurekahttp://testEureka001.com/eureka,http://testEureka002.com/eureka

然后在被注册的模块儿中的defaultZone值可以是http://testEureka001.com/eureka,http://testEureka002.com/eureka,http://testEureka003.com/eureka

4. Ribbon负载均衡

ribbon负责将用户的请求平摊的分配到服务器上,达到系统的HA(高可用)

模拟负载均衡

条件:当前有多个服务提个者(如:创建三个服务名相同的消费者,比如都是provider,相同接口返回不同数据)

创建一个新的Module,作为消费者

pom依赖如下

<dependencies>
    <!-- Ribbon依赖 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-ribbon</artifactId>
        <version>1.4.7.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka</artifactId>
        <version>1.4.7.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

配置文件如下

server:
  port: 8082
eureka:
  client:
    ## 向注册中心注册当前服务
    register-with-eureka: false
    service-url:
      defaultZone: http://localhost:9001/eureka/

创建一个config类,添加如下代码

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class ConfigBean {

    @Bean
    @LoadBalanced //负载均衡注释
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

创建一个controller类来创建接口

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
@RequestMapping("/test")
public class TestController {

    @Autowired
    private RestTemplate restTemplate;

    // 要调用的服务名称
    private static final String REST_SERVER_NAME = "http://PROVIDER";

    @GetMapping("/get")
    public String testGet() {
        return restTemplate.getForObject(REST_SERVER_NAME + "/test/get", String.class);
    }

    @PostMapping("/post")
    public String testPost(String data) {
        return restTemplate.postForObject(REST_SERVER_NAME + "/test/post", data, String.class);
    }
}

然后访问接口,然后不断刷新,会发现获取到的数据是不同的

修改负载均衡策略

可以在配置类(如上面的ConfigBean)中添加如下代码

@Bean
public IRule myIRule(){
    return new RandomRule();
}

以下是Ribbon包含的负载均衡策略

策略类名称描述
RandomRule随机策略随机选择server
RoundRobinRule轮询策略轮询选择, 轮询index,选择index对应位置的Server;
RetryRule重试策略对选定的负载均衡策略机上重试机制,在一个配置时间段内当选择Server不成功,则一直尝试使用subRule的方式选择一个可用的server;
BestAvailableRule最低并发策略逐个考察server,如果server断路器打开,则忽略,再选择其中并发链接最低的server
AvailabilityFilteringRule可用过滤策略过滤掉一直失败并被标记为circuit tripped的server,过滤掉那些高并发链接的server(active connections超过配置的阈值)或者使用一个AvailabilityPredicate来包含过滤server的逻辑,其实就就是检查status里记录的各个Server的运行状态;
ResponseTimeWeightedRule响应时间加权重策略根据server的响应时间分配权重,响应时间越长,权重越低,被选择到的概率也就越低。响应时间越短,权重越高,被选中的概率越高,这个策略很贴切,综合了各种因素,比如:网络,磁盘,io等,都直接影响响应时间
ZoneAvoidanceRule区域权重策略综合判断server所在区域的性能,和server的可用性,轮询选择server并且判断一个AWS Zone的运行性能是否可用,剔除不可用的Zone中的所有server

自定义策略

自定义策略不能在ComponentScan扫描范围内(不能与启动类同级或同级的包下)

创建自定义策略类,如下(具体算法逻辑请自己完善)

import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
import org.springframework.context.annotation.Configuration;

import java.util.List;

public class MyRule extends AbstractLoadBalancerRule {

    @Override
    public Server choose(Object o) {
        // 获取负载均衡器
        ILoadBalancer loadBalancer = getLoadBalancer();
        if (loadBalancer == null) {
            return null;
        }
        Server server = null;
        while (server == null){
            if (Thread.interrupted()) {
                return null;
            }
            // 获取所有服务器
            List<Server> allServers = loadBalancer.getAllServers();
            if (allServers.size() == 0) {
                return null;
            }
            // 获取可用服务器
            List<Server> reachableServers = loadBalancer.getReachableServers();

            //... 算法逻辑
        }
        return server;
    }

    @Override
    public void initWithNiwsConfig(IClientConfig iClientConfig) {

    }
}

然后定义一个策略配置类,如下

import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
import org.springframework.context.annotation.Configuration;

import java.util.List;

@Configuration
public class MyRuleConfig extends AbstractLoadBalancerRule {

    @Bean
    public IRule myRuleBean() {
        return new MyRule();
    }
}

然后在启动类上添加@RibbonClient(name = "PROVIDER", configuration = MyRuleConfig.class)注解

name:与当前服务相同名即可

configuration:自定义的策略类

持续更新中...

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

会功夫的李白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值