springcloud负载均衡Ribbon

springcloud负载均衡Ribbon

Ribbon的作用

​ 我们知道,微服务之间可以进行相互调用,我们一般把服务调用端称为消费者,而对于被调用端(提供者),可能存在多个,这时候需要一套算法去决定具体调用哪个服务,而Ribbon就起着这个作用,它能够把消费者请求分散在不同的服务上,起到负载均衡的作用。

1.定义三个微服务提供者,一个消费者,一个注册中心

image-20201014173228169

2.8001的代码如下

image-20201014173546943

@RestController
public class DeptController {
    
    

    @Autowired
    DeptService deptService;

    @Autowired
    DiscoveryClient discoveryClient;

    @RequestMapping("/dept/add")
    public boolean addDept(Dept dept) {
    
    
        return deptService.addDept(dept);
    }

    @RequestMapping("/dept/get/{id}")
    public Dept queryDeptById(@PathVariable("id") int id) {
    
    
        return deptService.queryDeptById(id);
    }

    @RequestMapping("/dept/list")
    public List<Dept> queryAllDept() {
    
    
        return deptService.queryAllDept();
    }

    @RequestMapping("/dept/discovery")
    public Object discovery() {
    
    
        //获取注册的服务列表清单
        List<String> services = discoveryClient.getServices();
        System.out.println("所有注册的服务为:"+services);

        List<ServiceInstance> instances = discoveryClient.getInstances("springcloud-provider-dept");

        for (ServiceInstance instance : instances) {
    
    

            System.out.println(
                    instance.getHost()+"/t"+
                    instance.getPort()+"/t"+
                    instance.getUri()+"/t"+
                    instance.getServiceId() );
        }

        return this.discoveryClient;
    }
}
@Mapper
@Repository
public interface DeptDao {
    
    

    public boolean addDept(Dept dept);

    public Dept queryDeptById(int id);

    public List<Dept> queryAllDept();
}
public interface DeptService {
    
    

    public boolean addDept(Dept dept);

    public Dept queryDeptById(int id);

    public List<Dept> queryAllDept();
}
@Service
public class DeptServiceImpl implements  DeptService {
    
    

    @Autowired
    DeptDao deptDao;

    public boolean addDept(Dept dept) {
    
    
        return deptDao.addDept(dept);
    }

    public Dept queryDeptById(int id) {
    
    
        return deptDao.queryDeptById(id);
    }

    public List<Dept> queryAllDept() {
    
    
        return deptDao.queryAllDept();
    }
}
@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
public class Provider_dept_8001 {
    
    
    public static void main(String[] args) {
    
    
        SpringApplication.run(Provider_dept_8001.class,args);
    }

}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.huang.dao.DeptDao">


    <insert id="addDept" parameterType="Dept">

        insert into dept(dname,db_source)
        values (#{dname},DATABASE())
   </insert>

    <select id="queryDeptById" resultType="Dept" parameterType="int">
       select * from  dept where  dno = #{dno}
    </select>


    <select id="queryAllDept" resultType="Dept" >
       select * from  dept
    </select>
</mapper>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <settings>
        <setting name="cacheEnabled" value="true"/>
      </settings>
</configuration>
server:
  port: 8001

mybatis:
  mapper-locations: classpath:mybatis/mapper/*.xml
  type-aliases-package: com.huang.pojo
  config-location: classpath:mybatis/mybatis-config.xml

spring:
  application:
    name: springcloud-provider-dept
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: org.gjt.mm.mysql.Driver
    username: root
    password: 123456
    url: jdbc:mysql://192.168.43.155:3306/db01?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true

#配置注册中心
eureka:
  client:
    service-url:
       defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7001.com:7001/eureka/,http://eureka7003.com:7003/eureka/
  instance:
    instance-id: springcloud-provider-dept8001  #修改eureka上的默认描述信息


info:
   app.name: testProvider
   company.name: testProvider
<?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>spring-cloud</artifactId>
        <groupId>com.huang</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springcloud-provider-dept-8001</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>

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

        <dependency>
            <groupId>com.huang</groupId>
            <artifactId>springcloud-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <!--日志-->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>

        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>

        </dependency>
        <!--数据库-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
        </dependency>
        <!--mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.1</version>
        </dependency>

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

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

        <!--热部署-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>

        <!--jetty-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jetty</artifactId>
        </dependency>
    </dependencies>
</project>

2.消费者和注册中心代码已经在springcloud注册中心eureka和SpringCloud 消费者和提供者这两篇文章中给出,这里不在提供。对于消费者需要改动的地方如下图

image-20201014174741596

image-20201014174931458

3.测试

image-20201014175134813

每次访问发现页面数据随机来源于不同的库,说明负载均衡成功了

自定义负载均衡算法

​ springcloud已经提供了很多中负载均衡算法,也可以自定义算法

系统提供的算法

image-20201014175627254

自定义算法

1.自定义算法相关代码不能放在和启动类相同的包下

image-20201014175850616

2.代码如下(每个服务访问五次再访问下一个)

public class MyRule extends AbstractLoadBalancerRule {
    
    


    public MyRule() {
    
    
    }

    private  int total=0;
    private int indexCur=0;

    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(total<=5){
    
    
                    server=allList.get(indexCur);
                    total++;
                }else {
    
    
                    total=0;
                    indexCur++;
                    if(indexCur>allList.size()-1){
    
    
                        indexCur=0;
                    }
                    server=allList.get(indexCur);
                }

                if (server == null) {
    
    
                    Thread.yield();
                } else {
    
    
                    if (server.isAlive()) {
    
    
                        return server;
                    }

                    server = null;
                    Thread.yield();
                }
            }

            return server;
        }
    }

  protected int chooseRandomInt(int serverCount) {
    
    
        return ThreadLocalRandom.current().nextInt(serverCount);
    }

    public Server choose(Object key) {
    
    
        return this.choose(this.getLoadBalancer(), key);
    }

    public void initWithNiwsConfig(IClientConfig clientConfig) {
    
    
    }
}
@Configuration
public class MyRuleConfig {
    
    

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

3.启动类上需要加上相关注解

image-20201014180105963

4测试访问就会走自定义的负载均衡算法

猜你喜欢

转载自blog.csdn.net/qq_34429554/article/details/109104286