Ribbon 和 wowza 的集成开发
来源:互联网 发布:图像坐标轴 知乎 编辑:程序博客网 时间:2024/06/06 08:58
前言
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 用的配置文件如下:
然后把这个文件放在你的 classpath 下。
3. 编写 LB 调用类
这个类将会给 ribbonLB 的 REST 请求返回一台服务器地址,如果请求失败,返回相应的错误码。这个类还提供了一个公开方法,用于动态调整负载均衡节点。
4. 编写动态修改负载均衡节点接口
6. 编辑 VHost.xml
编辑 %wowza%/conf/VHost.xml,把上边写的两个 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 配置的节点依旧是:
这样 REST 服务重启后,读取的负载均衡节点依旧是修改前的。如果你想在 REST 服务器断电重启后读取修改后的,最好把 Ribbon 属性在分布式缓存服务器中进行存放和读取,比如 Redis。另:本文示例代码已上传 CSDN 资源,下载地址:http://download.csdn.net/detail/defonds/7526359。
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 clientsample-client.ribbon.OkToRetryOnAllOperations=true# Interval to refresh the server list from the sourcesample-client.ribbon.ServerListRefreshInterval=2000# Connect timeout used by Apache HttpClientsample-client.ribbon.ConnectTimeout=3000# Read timeout used by Apache HttpClientsample-client.ribbon.ReadTimeout=3000# Initial list of servers, can be changed via Archaius dynamic property at runtimesample-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 configuration ConfigurationManager.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。
2 0
- Ribbon 和 wowza 的集成开发
- Ribbon 和 Eureka 的集成
- Ribbon 和 Eureka 的集成
- Memcached 与 Wowza 项目的集成
- MFC的Ribbon开发设计
- ribbon和feign的区别
- 使用JAVA和C#开发Ribbon界面
- 使用JAVA和C#开发Ribbon界面
- VBA开发Office 2007 Ribbon的方法
- VS2010/MFC编程入门之一(Ribbon界面开发:创建Ribbon样式的应用程序框架)
- 鸡啄米vc++2010系列44(Ribbon界面开发:创建Ribbon样式的应用程序框架)
- VS2010/MFC编程入门之五十二(Ribbon界面开发:创建Ribbon样式的应用程序框架)
- JSF和Hibernate、Spring的集成开发
- WOWZA的安装及(VOD+LIVE)简单配置和VLC RTP推流
- 使用 spring 集成 dbcp 数据库连接池到 Wowza 插件
- 超级rtmp服务器和屌丝wowza
- 超级rtmp服务器和屌丝wowza
- 超级rtmp服务器和屌丝wowza
- 网站翻译插件
- 高仿交通银行手机客户端界面
- 72_leetcode_Construct Binary Tree from Preorder and Inorder Traversal
- bzoj 1874 取石子游戏 题解 & SG函数初探
- db2 函数语法详解
- Ribbon 和 wowza 的集成开发
- C++标准库和stl区别
- linux之sed用法
- CString字符串截取
- 【IAR】设置和编译信息解析 程序运行耗时 内存分配MAP
- 将正则表达式匹配的强大功能带给 SQL
- Java 与 C++ 多态区别
- read by other session等待事件
- 【Python】分享一个大牛的Python教程