前言
        Ribbon 是提供 REST 服务的区域感知负载均衡器,它在 wowza 的前端,应该部署在专业的 REST 容器下,而不是流媒体服务器 wowza 下。

本文介绍了 Ribbon 和 wowza 的集成,Ribbon 作为 wowza 的一个插件部署在了 wowza 容器下,仅供 Ribbon 开发、部署的技术參考,现实中绝不可能出现这样的情况。由于 Wowza 毕竟不是专业提供 REST 服务的容器。关于 Ribbon 和 Wowza 真实场景的架构部署,请关注作者兴许博客。
        本文是在《让你的 wowza 服务器提供 RESTful web 服务》样例的基础上进一步进行研发。
        1. 新建 maven 项目
        參考《让你的 wowza 服务器提供 RESTful web 服务》步骤。新建的 maven 项目 defonds-server-module 例如以下:

        2. 编辑 Ribbon 配置文件
        依据你自己的集群。配置 Ribbon。比方作者 demo 用的配置文件例如以下:

# Max number of retries on the same server (excluding the first try)
sample-client.ribbon.MaxAutoRetries=1# Max number of next servers to retry (excluding the first server)
sample-client.ribbon.MaxAutoRetriesNextServer=1# Whether all operations can be retried for this client
sample-client.ribbon.OkToRetryOnAllOperations=true# Interval to refresh the server list from the source
sample-client.ribbon.ServerListRefreshInterval=2000# Connect timeout used by Apache HttpClient
sample-client.ribbon.ConnectTimeout=3000# Read timeout used by Apache HttpClient
sample-client.ribbon.ReadTimeout=3000# Initial list of servers, can be changed via Archaius dynamic property at runtime
sample-client.ribbon.listOfServers=www.baidu.com:80,www.163.com:80,www.csdn.net:80

然后把这个文件放在你的 classpath 下。
        3. 编写 LB 调用类

package com.defonds.wms.module.server;import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;import com.netflix.client.ClientException;
import com.netflix.client.ClientFactory;
import com.netflix.client.http.HttpRequest;
import com.netflix.client.http.HttpResponse;
import com.netflix.config.ConfigurationManager;
import com.netflix.niws.client.http.RestClient;
import com.wowza.wms.http.HTTProvider2Base;
import com.wowza.wms.http.IHTTPRequest;
import com.wowza.wms.http.IHTTPResponse;
import com.wowza.wms.logging.WMSLogger;
import com.wowza.wms.logging.WMSLoggerFactory;
import com.wowza.wms.vhost.IVHost;public class RibbonLBRestService extends HTTProvider2Base {private static final WMSLogger logger = WMSLoggerFactory.getInstance().getLoggerObj(RibbonLBRestService.class.getName());public static RestClient restClient = null;static {try {// Load the properties file using Archaius ConfigurationManagerConfigurationManager.loadPropertiesFromResources("sample-client.properties"); // Use ClientFactory to create client and the load balancerRibbonLBRestService.restClient = (RestClient) ClientFactory.getNamedClient("sample-client");  } catch (IOException e) {logger.error(e.getMessage(), e);}  }@Overridepublic void onHTTPRequest(IVHost arg0, IHTTPRequest request, IHTTPResponse response) {String jsonObject = null;response.setHeader("Content-Type", "application/json");try {String serverURI = RibbonLBRestService.getURI();response.setResponseCode(200);jsonObject = "{\"server_uri\":\"" + serverURI + "\"}";} catch (ClientException e2) {response.setResponseCode(400);jsonObject = "{\"error_code\":\"40039\"}";logger.error(e2.getMessage(), e2);} catch (URISyntaxException e3) {response.setResponseCode(400);jsonObject = "{\"error_code\":\"40023\"}";logger.error(e3.getMessage(), e3);} finally {// Get the printwriter object from response to write the required json object to the output stream      OutputStream out = response.getOutputStream();try {out.write(jsonObject.getBytes());out.flush();} catch (IOException e) {logger.error(e.getMessage(), e);}}}public synchronized static String getURI() throws ClientException, URISyntaxException {// Build the http request using the builder// Note that we only supply the path part (“/”) of the URI// The complete URI will be computed by the client once the server is chosen by the load balancerHttpRequest ribbonRequest = HttpRequest.newBuilder().uri(new URI("/")).build(); HttpResponse ribbonResponse;// Call client.executeWithLoadBalancer() API, not the execute() APIribbonResponse = RibbonLBRestService.restClient.executeWithLoadBalancer(ribbonRequest); return ribbonResponse.getRequestedURI().toString();}public synchronized static void changeServersPoolDynamically(String serverList) throws ClientException {// Dynamically change the server pool from the configurationConfigurationManager.getConfigInstance().setProperty("sample-client.ribbon.listOfServers", serverList); logger.debug("changing servers ...");try {// Wait until server list is refreshed (2 seconds refresh interval defined in properties file)Thread.sleep(3000); } catch (InterruptedException e) {logger.error(e.getMessage(), e);} }}

这个类将会给 ribbonLB 的 REST 请求返回一台服务器地址。假设请求失败,返回对应的错误码。

这个类还提供了一个公开方法,用于动态调整负载均衡节点。
        4. 编写动态改动负载均衡节点接口

package com.defonds.wms.module.server;import java.io.IOException;
import java.io.OutputStream;import com.netflix.client.ClientException;
import com.wowza.wms.http.HTTProvider2Base;
import com.wowza.wms.http.IHTTPRequest;
import com.wowza.wms.http.IHTTPResponse;
import com.wowza.wms.logging.WMSLogger;
import com.wowza.wms.logging.WMSLoggerFactory;
import com.wowza.wms.vhost.IVHost;public class RibbonChangeInstanceService extends HTTProvider2Base {private static final WMSLogger logger = WMSLoggerFactory.getInstance().getLoggerObj(RibbonChangeInstanceService.class.getName());@Overridepublic void onHTTPRequest(IVHost arg0, IHTTPRequest request, IHTTPResponse response) {String serverList = request.getParameter("server_list");// TODO Authorization// TODO serverList str checkString jsonObject = null;response.setHeader("Content-Type", "application/json");try {RibbonLBRestService.changeServersPoolDynamically(serverList);response.setResponseCode(200);jsonObject = "{\"error_code\":\"0\"}"; // server list is changed successfully} catch (ClientException e2) {response.setResponseCode(400);jsonObject = "{\"error_code\":\"40039\"}";logger.error(e2.getMessage(), e2);} finally {// Get the printwriter object from response to write the required json object to the output stream      OutputStream out = response.getOutputStream();try {out.write(jsonObject.getBytes());out.flush();} catch (IOException e) {logger.error(e.getMessage(), e);}}} }

这个类提供了一个用于动态改动负载均衡节点池的接口。假设改动成功返回错误码为 0,否则为其它值。

5. 编辑 maven 依赖

编辑项目 pom.xml。将上边依赖到的包导入:

     <!-- ribbon --><dependency><groupId>com.netflix.ribbon</groupId><artifactId>ribbon-core</artifactId><version>0.3.12</version></dependency><dependency><groupId>com.netflix.ribbon</groupId><artifactId>ribbon-httpclient</artifactId><version>0.3.12</version></dependency>

6. 编辑 VHost.xml
        编辑 %wowza%/conf/VHost.xml,把上边写的两个 HTTPProvider 加入进去:

                    <HTTPProvider><BaseClass>com.defonds.wms.module.server.RibbonLBRestService</BaseClass><RequestFilters>ribbonLB*</RequestFilters><AuthenticationMethod>none</AuthenticationMethod></HTTPProvider><HTTPProvider><BaseClass>com.defonds.wms.module.server.RibbonChangeInstanceService</BaseClass><RequestFilters>ribbonChange*</RequestFilters><AuthenticationMethod>none</AuthenticationMethod></HTTPProvider>

7. 项目又一次打包部署
        命令行切换到你的 defonds-server-module 项目文件夹下,运行
mvn package
        8. 訪问接口

        debug 启动 defonds-server-module,然后在浏览器訪问 http://localhost:1935/ribbonLB,以向 Ribbon 要一个服务器地址,返回结果例如以下:
{"server_uri":"http://www.csdn.net:80/"}
        返回的是服务器 URL 是 http://www.csdn.net:80/。然后在浏览器訪问 http://localhost:1935/ribbonChange?server_list=www.qq.com:80,www.126.com:80。以动态调整负载均衡节点。返回结果例如以下:
{"error_code":"0"}
        这个返回码说明已经调整成功。我们能够继续訪问 http://localhost:1935/ribbonLB 验证一下,返回结果是:
{"server_uri":"http://www.qq.com:80/"}
        没错,确实成功了。

注意
        以上 Ribbon 动态调整的负载均衡节点是内存里的配置。服务器下的 sample-client.properties 配置的节点依然是:

sample-client.ribbon.listOfServers=www.baidu.com:80,www.163.com:80,www.csdn.net:80

这样 REST 服务重新启动后。读取的负载均衡节点依然是改动前的。假设你想在 REST 服务器断电重新启动后读取改动后的。最好把 Ribbon 属性在分布式缓存服务器中进行存放和读取,比方 Redis。

另:本文演示样例代码已上传 CSDN 资源。下载地址:http://download.csdn.net/detail/defonds/7526359。

Ribbon 和 wowza 的集成开发相关推荐

  1. 【JAVA零基础入门系列】Day2 Java集成开发环境IDEA

    [JAVA零基础入门系列](已完结)导航目录 Day1 开发环境搭建 Day2 Java集成开发环境IDEA Day3 Java基本数据类型 Day4 变量与常量 Day5 Java中的运算符 Day ...

  2. RStudio v1.2.1335 发布,R 语言的集成开发环境

    开发四年只会写业务代码,分布式高并发都不会还做程序员? >>>   RStudio 是 R 语言的集成开发环境,分为面向桌面用户 IDE 和 Linux R 服务器版编辑器两种编辑器 ...

  3. 分享:Arcadia 0.12.1 发布,Ruby 集成开发环境

    Arcadia 0.12.1 发布,Ruby 集成开发环境 http://www.oschina.net/news/35942/arcadia-0-12-1

  4. C语言的集成开发环境

    Code::Blocks,开源免费的C/C++ IDE CodeLite,开源.跨平台的C/C++集成开发环境 Dev-C++,可移植的C/C++IDE C-Free Light Table Visu ...

  5. 强烈推荐一款完全免费的绿色JRE+Tomcat+MySQL集成开发工具 - JTM

    为什么80%的码农都做不了架构师?>>>    因为工作需要经常要将JSP项目拿到客户电脑上进行演示,但客户经常在安装配置JDK.Tomcat.MySQL的过程中出现很多问题,给客户 ...

  6. 使用IntelliJ IDEA 13搭建Android集成开发环境(图文教程)

    ​[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/ ...

  7. python有哪些常见的开发环境_Python集成开发环境有哪些

    对于Python集成开发环境,你更喜欢哪一款? 0.Spyder Spyder是Python(x,y)的作者为它开发的一个简单的集成开发环境.和其他的Python开发环境相比,它最大的优点就是模仿MA ...

  8. 组态王浏览器java_1工程浏览器是组态王的集成开发环境在这里可以

    您所在位置:网站首页 > 海量文档 &nbsp>&nbsp计算机&nbsp>&nbsp软件工程 1工程浏览器是组态王的集成开发环境在这里可以3页 本文 ...

  9. arduino与java,Arduino具有与Java和C语言类似的IDE集成开发环境和图形化编程环境

    Arduino具有与Java和C语言类似的IDE集成开发环境和图形化编程环境 更多相关问题 听力原文:W: Hi, Steve, good to see you are up and around a ...

  10. Python编辑器与集成开发环境(IDE)选择

    上一篇文章记录了怎么安装Python环境,同时也成功的在电脑上安装好了Python环境,可以正式开始自己的编程之旅了.但是现在又有头疼的事情,该用什么来写Python程序呢,该用什么来执行Python ...

最新文章

  1. c++中几种常见的类型转换。int与string的转换,float与string的转换以及string和long类型之间的相互转换。to_string函数的实现和应用。...
  2. 菜鸟程序员的成长之路-工作篇
  3. JSP关于Frameset的简单用法
  4. window2003 server的一些优化设置_windows 2003
  5. 我的第一个REST客户端程序!
  6. 无法执行该VI,必须使用LabVIEW完整版开发系统才可以解决该错误
  7. 六招让你成职场超男超女
  8. Docker 运行Tensorboard 和 jupyter的正确方法
  9. torch 默认参数初始化_Detection学习之九-torch中如何定义优化器及调整学习率
  10. 重装系统时提示在引导修复时检测到错误怎么办
  11. 大学英语综合教程三 Unit 2 课文内容英译中 中英翻译
  12. vue 总结一项目建立及文件夹结构配置
  13. 腾讯小程序php,微信小程序实现使用腾讯地图SDK步骤详细介绍
  14. configure配置安装详解
  15. 【BUGKU之ez_java_serialize】
  16. SpringBoot JPA 批量插入实现,使用原生sql解决SaveAll插入慢的问题
  17. 【剪映】基础剪辑 | 实用技巧
  18. ai计算机当前不支持的字体,字体arial不支持样式regular的解决方法
  19. Win2008 - R2 下安装 MsSqlServer2008
  20. 2020电力计算机英语,粤电力B:2020年年度报告(英文版)

热门文章

  1. 《通信技术 - 以太网》详解以太网(二)
  2. 《Java多线程编程核心技术》学习笔记(1)
  3. 来料不良,只是采购一人的事吗?
  4. win7安装中文语言包
  5. 盘点2009:Office办公软件谁主江湖
  6. 5套精美的石器时代游戏官方网页源码
  7. 动态推荐系统关键技术研究(一)
  8. Visual FoxPro 6.0~9.0解决方案与范例大全写作原稿及光盘下载
  9. AIDA64 Extreme Edition(硬件检测)多国语言绿色特别版
  10. 前端页面插入Flash动画