微服务架构之均衡组件 Ribbon解析:进阶应用(完结)

举报
qingting-fly 发表于 2021/09/26 20:22:29 2021/09/26
【摘要】 使用Netty发送网络请求 Ribbon除了可以和RestTemplate,Feign一起使用之外,还可以与Netty进行集成,也就是说,Ribbon使用负载均衡策略选择完服务器之后,然后再交给Netty进行网络请求。 其实,上一篇文章的介绍的Ribbon的LoadBalancerCommand的submit函数可以直接使用Netty框架,也就是在ServerOperation的call函...

使用Netty发送网络请求

Ribbon除了可以和RestTemplateFeign一起使用之外,还可以与Netty进行集成,也就是说,Ribbon使用负载均衡策略选择完服务器之后,然后再交给Netty进行网络请求。
 其实,上一篇文章的介绍的RibbonLoadBalancerCommandsubmit函数可以直接使用Netty框架,也就是在ServerOperationcall函数中使用Netty代替HttpURLConnection来发送网络请求。但是,Ribbon已经替使用者们封装好了与Netty进行集成的相关实现。
RibbonTransport封装了生成LoadBalancingHttpClient<ByteBuf, ByteBuf>对象的各类工厂函数。使用LoadBalancingHttpClient<ByteBuf, ByteBuf>submit发送网络请求,底层默认使用Netty框架来进行网络请求。ByteBufNetty框架内的字符串缓存实例。

public class SimpleGet {
    @edu.umd.cs.findbugs.annotations.SuppressWarnings
    public static void main(String[] args) throws Exception {
        LoadBalancingHttpClient<ByteBuf, ByteBuf> client = RibbonTransport.newHttpClient();
        //HttpClientRequest.createGet接口可以直接生成对应的请求
        HttpClientRequest<ByteBuf> request = HttpClientRequest.createGet("http://www.google.com/");
        final CountDownLatch latch = new CountDownLatch(1);
        //
        client.submit(request)
            .toBlocking()
            .forEach(new Action1<HttpClientResponse<ByteBuf>>() {
                @Override
                public void call(HttpClientResponse<ByteBuf> t1) {
                    System.out.println("Status code: " + t1.getStatus());
                    t1.getContent().subscribe(new Action1<ByteBuf>() {

                        @Override
                        public void call(ByteBuf content) {
                            //可以直接对Netty的ByteBuf进行操作
                            System.out.println("Response content: " + content.toString(Charset.defaultCharset()));
                            latch.countDown();
                        }
                        
                    });
                }
            });
        latch.await(2, TimeUnit.SECONDS);
    }
}

只读数据库的负载均衡实现

 读者在学习了FeignLoadBalancer的原理和Ribbon的API之后,可以为任何需要负载均衡策略的项目添加Ribbon的集成。

 比如一个的数据库中间件项目,它支持多个读库的数据读取,它希望对多个的读库进行数据读取时可以支持一定的负载均衡策略。那么,读者就可以通过集成Ribbon来实现读库之间的负载均衡。
 首先,你需要定义DBServer类来继承RibbonServer类,来存储只读数据库服务器的状态信息,比如说IP地址,数据库连接数,平均请求响应时间等。
 然后再定义一个DBLoadBalancer来继承BaseLoadBalancer类,示例代码中直接使用WeightedResponseTimeRuleDBServer列表进行负载均衡的选择,然后使用自定义的DBPing来检测数据库是否可用。

public DBLoadBalancer buildFixedDBServerListLoadBalancer(List<DBServer> servers) {
        IRule rule = new WeightedResponseTimeRule();
        IPing ping = new DBPing();
        DBLoadBalancer lb = new DBLoadBalancer(config, rule, ping);
        lb.setServersList(servers);
        return lb;
    }

 而使用DBLoadBalancer的过程也很简单,通过LoadBalancerCommandwithLoadBalancer来使用它,然后在submit的回调函数中使用选出的数据库和SQL语句交给其他组件来执行SQL操作。

public class DBConnectionLoadBalancer {

    private final ILoadBalancer loadBalancer;
    private final RetryHandler retryHandler = new DefaultLoadBalancerRetryHandler(0, 1, true);

    public DBConnectionLoadBalancer(List<DBServer> serverList) {
        loadBalancer = LoadBalancerBuilder.newBuilder().buildFixedDBServerListLoadBalancer(serverList);
    }

    public String executeSQL(final String sql) throws Exception {
        //使用LoadBalancerCommand来进行负载均衡,具体策略可以在Builder中进行设置。
        return LoadBalancerCommand.<String>builder()
                .withLoadBalancer(loadBalancer)
                .build()
                .submit(new ServerOperation<String>() {
                    @Override
                    public Observable<String> call(Server server) {
                        URL url;
                        try {
                            return Observable.just(DBManager.execute(server, sql));
                        } catch (Exception e) {
                            return Observable.error(e);
                        }
                    }
                }).toBlocking().first();
    }
}

ILoadBalancer通过一定的负载策略从读数据库列表中选出一个数据库来让DBManager执行SQL语句,通过这种方式,读者就可以实现读数据库的负载均衡机制。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。