这一节里主要讲解osmp的服务发现与路由。osmp通过osmp-http组件对外发布了一个cxf的restful服务,所有的请求都通过这个restful这个接口接受请求并解析请求后再调用osgi的服务完成请求后返回到前端。
request->osmp-http的restful接口->解析请求->osgi服务发现->服务路由->调用服务->返回-->组装返回参数->返回
osmp通过osmp-service组件来对服务进行统一管理,主要功能包括服务的监听、bundle的监听、服务容器管理、服务注册到zookeeper等功能。
在osgi里可以通过ServiceTracker 服务跟踪器来跟踪某一类接口服务的新增、修改、删除等操作,通过BundlerContext.addBundleListener()注册 bundle监听器(BundleListener)来监听bundle各生命周期的事件,比如bundle的安装、卸载、更新、启动、停止等事件。
osmp为了便于对服务的统一管理,要求所有的服务都必须实现 osmp-intf-define里的定义的BaseDataService接口。这样我们就可以通过服务跟踪器跟踪到BaseDataService接口的服务新增、修改、删除等事件!
具体代码可以参照osmp-service里 ServiceWatcher.java类
/* * Project: OSMP * FileName: ServiceWatcher.java * version: V1.0 */ package com.osmp.service.watch; import java.util.Date; import java.util.UUID; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleEvent; import org.osgi.framework.BundleListener; import org.osgi.framework.ServiceReference; import org.osgi.util.tracker.ServiceTracker; import org.osgi.util.tracker.ServiceTrackerCustomizer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.osgi.context.BundleContextAware; import org.springframework.util.Assert; import com.osmp.intf.define.config.FrameConst; import com.osmp.intf.define.interceptor.ServiceInterceptor; import com.osmp.intf.define.service.BaseDataService; import com.osmp.intf.define.service.ZookeeperService; import com.osmp.service.bean.DataServiceInfo; import com.osmp.service.bean.InterceptorInfo; import com.osmp.service.factory.ServiceFactoryImpl; import com.osmp.service.manager.ServiceStateManager; import com.osmp.service.registration.ServiceContainer; import com.osmp.service.util.ServiceUtil; import com.osmp.utils.net.RequestInfoHelper; /** * * Description:服务注册、注销、监听 * @author: wangkaiping * @date: 2016年8月9日 上午10:27:15上午10:51:30 */ public class ServiceWatcher implements BundleContextAware, InitializingBean, DisposableBean { private Logger logger = LoggerFactory.getLogger(ServiceWatcher.class); private ServiceTracker dataServiceTracker; private ServiceTracker serviceInterceptorTracker; private ServiceStateManager serviceStateManager; private ServiceFactoryImpl serviceFactoryImpl; private BundleContext context; private ZookeeperService zookeeper; private final static String NODE_CHANGE = "/osmp/nodechange"; @Override public void setBundleContext(BundleContext context) { this.context = context; } public void setServiceFactoryImpl(ServiceFactoryImpl serviceFactoryImpl) { this.serviceFactoryImpl = serviceFactoryImpl; } public void setServiceStateManager(ServiceStateManager serviceStateManager) { this.serviceStateManager = serviceStateManager; } public void setZookeeper(ZookeeperService zookeeper) { this.zookeeper = zookeeper; } @Override public void destroy() throws Exception { if (dataServiceTracker != null) { dataServiceTracker.close(); } if (serviceInterceptorTracker != null) { serviceInterceptorTracker.close(); } logger.info("服务监听结束"); } @Override public void afterPropertiesSet() throws Exception { Assert.notNull(context); Assert.notNull(serviceStateManager); Assert.notNull(serviceFactoryImpl); dataServiceTracker = new ServiceTracker(context, BaseDataService.class.getName(), new DataServiceTrackerCustomizer()); serviceInterceptorTracker = new ServiceTracker(context, ServiceInterceptor.class.getName(), new ServiceInterceptorTrackerCustomizer()); dataServiceTracker.open(true); serviceInterceptorTracker.open(true); context.addBundleListener(new BundleListener() { @Override public void bundleChanged(BundleEvent event) { if (event.getType() == BundleEvent.UNINSTALLED) { String name = event.getBundle().getSymbolicName(); try { logger.info("uninstall bundle " + name); zookeeper.deleteNodeByBundle(name); ServiceWatcher.this.nodeUpdate(); } catch (Exception e) { logger.error( "zookeeper delete service by bundle, bundle name : " + name, e); } } } }); logger.info("服务监听启动"); } // dataService监听 private class DataServiceTrackerCustomizer implements ServiceTrackerCustomizer { @Override public Object addingService(ServiceReference reference) { BaseDataService bsService = (BaseDataService) context.getService(reference); String bundleName = reference.getBundle().getSymbolicName(); String bundleVersion = reference.getBundle().getVersion().toString(); Object name = reference.getProperty(FrameConst.SERVICE_NAME); if (name == null || "".equals(name)) { logger.error("组件" + bundleName + "(" + bundleVersion + ") dataService服务name未设置"); return bsService; } Object mark = reference.getProperty(FrameConst.SERVICE_MARK); ServiceContainer.getInstance().putDataService(bundleName, bundleVersion, name.toString(), bsService); DataServiceInfo info = new DataServiceInfo(); info.setBundle(bundleName); info.setVersion(bundleVersion); info.setName(name.toString()); info.setState(1); info.setUpdateTime(new Date()); info.setMark(mark == null ? "" : mark.toString()); serviceStateManager.updateDataService(info); String path = ZookeeperService.ROOT_PATH + ZookeeperService.SERVICE + "/" + RequestInfoHelper.getLocalIp() + "/"; logger.debug("register service path: " + path + " bundle : " + bundleName + " to zookeeper "); ServiceWatcher.this.registerService(path, info); return bsService; } @Override public void modifiedService(ServiceReference reference, Object service) { } @Override public void removedService(ServiceReference reference, Object service) { String bundleName = reference.getBundle().getSymbolicName(); String bundleVersion = reference.getBundle().getVersion() .toString(); Object name = reference.getProperty(FrameConst.SERVICE_NAME); if (name == null || "".equals(name)) { logger.error("组件" + bundleName + "(" + bundleVersion + ") dataService服务name未设置"); return; } ServiceContainer.getInstance().removeDataService(bundleName, bundleVersion, name.toString()); Object mark = reference.getProperty(FrameConst.SERVICE_MARK); DataServiceInfo info = new DataServiceInfo(); info.setBundle(bundleName); info.setVersion(bundleVersion); info.setName(name.toString()); info.setState(0); info.setMark(mark == null ? "" : mark.toString()); info.setUpdateTime(new Date()); serviceStateManager.updateDataService(info); System.out.println("===============remove service bundleName:" + bundleName + " name: " + name.toString() + " mark: " + mark.toString()); String path = ZookeeperService.ROOT_PATH + ZookeeperService.SERVICE + "/" + RequestInfoHelper.getLocalIp() + "/"; ServiceWatcher.this.unRegisterService(path, info); } } // ServiceInterceptor监听 private class ServiceInterceptorTrackerCustomizer implements ServiceTrackerCustomizer { @Override public Object addingService(ServiceReference reference) { ServiceInterceptor sicpt = (ServiceInterceptor) context.getService(reference); String bundleName = reference.getBundle().getSymbolicName(); String bundleVersion = reference.getBundle().getVersion().toString(); Object name = reference.getProperty(FrameConst.SERVICE_NAME); if (name == null || "".equals(name)) { logger.error("组件" + bundleName + "(" + bundleVersion + ") serviceInterceptor服务name未设置"); return sicpt; } Object mark = reference.getProperty(FrameConst.SERVICE_MARK); ServiceContainer.getInstance().putInterceptor( ServiceUtil.generateServiceName(bundleName, bundleVersion, name.toString()), sicpt); InterceptorInfo info = new InterceptorInfo(); info.setBundle(bundleName); info.setVersion(bundleVersion); info.setName(name.toString()); info.setState(1); info.setUpdateTime(new Date()); info.setMark(mark == null ? "" : mark.toString()); serviceStateManager.updateServiceInterceptor(info); return sicpt; } @Override public void modifiedService(ServiceReference reference, Object service) { } @Override public void removedService(ServiceReference reference, Object service) { String bundleName = reference.getBundle().getSymbolicName(); String bundleVersion = reference.getBundle().getVersion().toString(); Object name = reference.getProperty(FrameConst.SERVICE_NAME); if (name == null || "".equals(name)) { logger.error("组件" + bundleName + "(" + bundleVersion + ") serviceInterceptor服务name未设置"); return; } Object mark = reference.getProperty(FrameConst.SERVICE_MARK); ServiceContainer.getInstance().removeInterceptor( ServiceUtil.generateServiceName(bundleName, bundleVersion, name.toString())); InterceptorInfo info = new InterceptorInfo(); info.setBundle(bundleName); info.setVersion(bundleVersion); info.setName(name.toString()); info.setState(0); info.setMark(mark == null ? "" : mark.toString()); info.setUpdateTime(new Date()); serviceStateManager.updateServiceInterceptor(info); } } /** * 向zookeeper注册服务 * * @param path * @param ds */ public void registerService(String path, DataServiceInfo ds) { String bundle = ds.getBundle(); String cname = ds.getMark(); String name = ds.getName(); String version = ds.getVersion(); String status = String.valueOf(ds.getState()); try { if (!zookeeper.exists(path + name)) { zookeeper.createNode(path + name); } if (!zookeeper.exists(path + name + "/bundle")) { zookeeper.createNode(path + name + "/bundle", bundle); } else { zookeeper.setNodeData(path + name + "/bundle", bundle); } if (!zookeeper.exists(path + name + "/cname")) { zookeeper.createNode(path + name + "/cname", cname); } else { zookeeper.setNodeData(path + name + "/cname", cname); } if (!zookeeper.exists(path + name + "/version")) { zookeeper.createNode(path + name + "/version", version); } else { zookeeper.setNodeData(path + name + "/version", version); } if (!zookeeper.exists(path + name + "/status")) { zookeeper.createNode(path + name + "/status", status); } else { zookeeper.setNodeData(path + name + "/status", status); } this.nodeUpdate(); } catch (Exception e) { e.printStackTrace(); logger.error("zookeeper register service fail, service name : " + name, e); } } /** * 卸载服务 * * @param path * @param ds */ public void unRegisterService(String path, DataServiceInfo ds) { String name = ds.getName(); try { if (zookeeper.exists(path + name + "/status")) { zookeeper.setNodeData(path + name + "/status", String.valueOf(ds.getState())); this.nodeUpdate(); } } catch (Exception e) { e.printStackTrace(); logger.error("zookeeper unRegister service fail, service name : " + name, e); } } /** * 更新节点状态变化 */ public void nodeUpdate(){ String data = UUID.randomUUID().toString(); try { if(zookeeper.exists(NODE_CHANGE)){ zookeeper.setNodeData(NODE_CHANGE, data); }else{ zookeeper.createNode(NODE_CHANGE); zookeeper.setNodeData(NODE_CHANGE, data); } } catch (Exception e) { logger.error("更新节点变化状态错误", e); } } }
- ServiceWatcher 实现 BundleContextAware接口,将BundleContext 设置进来。
- 在ServiceWatcher初始化的时候 实例化了两个服务跟踪器 (ServiceTracker)分别用来跟踪 BaseDataService、ServiceInterceptor 两类接口的服务。
- 在ServiceWatcher初始化的时候 给BundleContext新增Bunlde监听用来监听bundle的事件
- ServiceTracker需要传递一个ServiceTrackerCustomizer实例来具体执行监听的事件,在这里我们通过DataServiceTrackerCustomizer来具体执行BaseDataService接口服务跟踪操作。
- 当BaseDataService 服务被发布到osgi容器里的时候,会自动调用DataServiceTrackerCustomizer.addingService(ServiceReference reference) 方法,通过BundleContext.getService(ServiceReference reference),我们可以获取到当前被发布到osgi容器里的服务。
- 通过获取bundleName、bundleVersion、以前发布服务时定义的tag标签(name)组成唯一的key(bundleName+bundleVersion+name) 以获取到service为value。将此保存到服务容器(Map)里。
注:osmp-service里将监听到的服务同时保存到数据库里和注册到zookeeper请暂时忽略,稍后osmp注册中会作详细讲解。
服务发现和路由:
osmp-http接收到请求后解析服务名称,通过服务查询此服务是否绑定了拦截器,如果绑定了拦截器,则先执行拦截器链,拦截器如果执行失败则直接返回,如果拦截器执行成功则通过服务名称获取服务,获取服务成功后直接执行服务的execute方法,将并结果返回!
这里讲的简单点儿,具体osmp封装了一层代理实现,有兴趣的可以直接查看osmp-http源码。
至此osmp的服务发现和服务调用功能就讲到这里!
相关推荐
5. **Blueprint或Declarative Services**:这两种是OSGi中的服务配置方式,Blueprint更接近XML,而Declarative Services使用注解,简化了服务的声明和管理。 6. **远程服务**:OSGi Remote Services允许Bundle之间...
2. **服务导向**:OSGi提供了一种服务注册和发现机制,允许模块之间通过服务进行通信,增强了组件间的解耦。 3. **动态性**:OSGi环境中,bundle可以在运行时动态地安装、启动、停止、更新和卸载,这对于软件维护和...
网上收集的OSGI资料. 包括: OSGi原理与最佳实践(精选版).pdf OSGI实战和源码.rar osgi进阶.pdf Introduce.OSGi.ppt OSGi.in.action.ppt r4.cmpn.pdf r4.core.pdf r4.enterprise.pdf
技术角度可能包括了OSGI的模块化结构、服务发现机制以及如何管理模块间的依赖。 三. OSGI带来什么 这部分将探讨OSGI为开发者和企业带来的好处,例如: 1. 动态性:OSGI允许在运行时安装、卸载、更新模块,无需重启...
1. **OSGi基础**:介绍OSGi的核心概念,如模块系统(称为"bundle"),服务注册和发现机制,以及如何将Java应用程序划分为独立的模块。 2. **模块化开发**:讲解如何使用OSGi模块化你的代码,减少依赖冲突,提高代码...
**OSGI实战教程** OSGI(Open Service Gateway Initiative)是一种开放标准,用于创建模块化Java应用程序。它通过提供一个服务导向的架构,使得组件可以独立地安装、升级、激活和停用,从而解决了Java应用程序的...
这个压缩包包含了关于OSGI的重要文档,分别是“OSGi R4核心规范文档”、“OSGi服务文档”以及“OSGi-最佳原理与实践”(王昊编著)。下面将详细介绍这些文档所涵盖的关键知识点。 首先,"OSGi R4核心规范文档"是...
标题和描述均聚焦于“OSGi理论与实战”,这一主题涉及了OSGi规范R4.1的核心概念、实现机制,以及如何基于Equinox框架开发和扩展OSGi-Based应用,包括分布式OSGi的深入探讨。以下将对这些知识点进行详细解析。 ### ...
OSGI原理与最佳实践的完整版,共12章 第1 章OSGi 简介 第2 章OSGi 框架简介 第3 章基于Spring-DM 实现Petstore 第4 章基于Apache CXF 实现分布式Petstore 第5 章构建OSGI Bundle Repositor'y 第6 章OSGi 规范解读 ...
资源名称:OSGI原理与最佳实践内容简介:国内第一本OSGi图书OSGi国内推广者林昊多年经验的结晶涵盖OSGi从入门到深入的知识体系引领OSGi国内研究和普及本书基于作者多年使用OSGi的经验而编写,涵盖了OSGi从入门到深入...
OSGi(Open Services Gateway ...使用者可以通过启动对应的bundle来选择执行加法还是乘法运算,展示了OSGi框架在动态服务发现和交互方面的强大能力。这样的设计对于构建可扩展、可维护的Java应用程序非常有价值。
9. **实战应用**:"OSGI实战.pdf"可能包含实际项目案例,演示如何在真实场景中应用OSGI解决特定问题。 通过阅读这份文档和解压后的"dist.rar"和"code.rar"文件,你不仅可以深入了解OSGI技术,还能获得实践经验,...
OSGi学习不错的材料 OSGi学习不错的材料 OSGi学习不错的材料 OSGi学习不错的材料
6. "OSGI实战及例子(普通下载).rar":这个资源可能包含更多的实战项目和示例代码,对于动手实践非常有帮助。 通过对这些书籍的学习和实践,开发者能够全面理解OSGi的机制,掌握如何在项目中有效应用OSGi,从而构建...
OSGi 服务发布和获取方式 OSGi(Open Service Gateway Initiative)是一种动态模块化的服务平台,能够动态地管理和部署服务。OSGi 服务发布和获取方式是 OSGi 框架中的一种核心机制,用于发布和获取服务。下面将...
在IT行业中,Eclipse是一款广泛使用的Java开发集成环境,而Spring框架则是企业级应用开发的首选框架之一。OSGi(Open Services Gateway Initiative)则是一种模块化系统和Java应用程序框架,它允许开发者创建可热...
其后进入OSGi实战,结合实例讲解如何基于OSGi框架编写模块化、动态化的各种Java应用;最后对OSGi知识进行深入讲解,通过对OSGi规范和实现框架(Equinox、Felix、Spring-DM和Apache CXF)的分析,以及最佳实践的介绍...
当一个组件提供了服务,它会在OSGI服务注册表中注册该服务,其他组件则可以通过查询注册表来发现并使用这些服务。这种服务模型使得OSGI系统具有高度的灵活性和可扩展性,因为服务的提供和消费是解耦的,可以在运行时...