Talk is Cheap, Show me the Code! <<网站首页文章列表

  • jar包冲突的另一种有效解决方法

    青山隐隐水迢迢,秋尽江南草未凋。 二十四桥明月夜,玉人何处教吹箫? 旧项目整合MongoDB发生了意外最近有个新需求,需要在现有项目中整合MongoDB,这还不是轻车熟路。这个项目Copy一段,那个项目抄一截,轻轻松松啊。转眼间,开始了单元测试。插入数据,很成功。接着只要更新数据没问题,这个任务就简简单单完成了。众所周知,要是更新也没问题,就不会有这篇文章了。接下来看看让我懵B的错误:javajava.lang.IllegalAccessError: tried to access class org.springframework.beans.PropertyMatches from class org.springframework.data.mapping.PropertyReferenceException at org.springframework.data.mapping.PropertyReferenceException.detectPotentialMatches(PropertyReferenceException.java:134) at org.springframework.data.mapping.PropertyReferenceException.(PropertyReferenceException.java:59) at org.springframework.data.mapping.PropertyPath.(PropertyPath.java:75) at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:327) at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:307) at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:270) at org.springframework.data.mongodb.core.convert.QueryMapper$MetadataBackedField.getPath(QueryMapper.java:837) at org.springframework.data.mongodb.core.convert.QueryMapper$MetadataBackedField.(QueryMapper.java:729) at org.springframework.data.mongodb.core.convert.QueryMapper$MetadataBackedField.(QueryMap

    mongoDB   Spring   IllegalAccessError   2020-07-22 浏览(78) 阅读原文>>
  • 君子性非异也,善假于物也——功能强大的Postman

    君子性非异也,善假于物物也!相信大部分开发人员,尤其是后端开发,都听过postman这款堪称神器的软件吧。它的一切都是为API而生的:+ 管理API:创建、更新、删除、执行我们开发的接口+ 分享API:可以将我们编写的接口共享给小组其他成员,比如将写好的并经过良好自测的接口提供给前端同学+ 控制API版本:通过版本号,我们可以同时管理接口的多个版本+ API的自动化测试:通过postman,我们可以很简单的就是实现接口的断言测试下面我们就先从入门使用开始介绍postman的常用功能和技巧吧。------ 基础我使用的是postman的mac版本,所以后续的介绍都是基于这个版本的。当我们打开postman之后,在Collections菜单中默认是没有内容的,不过官网已经为我们准备了一个[完整的学习样例](https://docs.postman-echo.com/)。打开这个网站之后,你会看到如下页面:![blockimg](https://oomabc.com/staticsrc/img/201909/21/15690767925025a5fef3bbd3b4eabacd8de6ef572638b.jpg)这是学习样例的共享API页面,也就是接口文档页面,我们直接点击右上角的Run in Postman按钮,浏览器会打开我们本地的Postman软件然后倒入整个学习样例接口:![blockimg](https://oomabc.com/staticsrc/img/201909/21/1569077253599adc167d2da9b4c429033da442d85c76d.jpg) 集合(Collection)+文件夹(Folder)左边Collections中,Postman Echo就是一个API集合,而里面的Request Methods或者Headers就是这个集合下的细分文件夹。所以,我们针对一个独立的项目可以创建一个Collections,然后为不同的模块创建不同的文件夹。你可以随意运行学习样例中的几个Request,有个初步的感觉。 接口文档当我们完成了一些接口的开发及自测之后,就可以将这

    API   Postman   2020-05-31 浏览(538) 阅读原文>>
  • 实现一个关于队列的伪需求是一种怎样的体验

    最近花了一天的时间,在实现一个关于队列扩展的伪需求。就是当队列消息有积累的时候,如果对队列中的消息进行去重,或者说在一定范围内去重。 场景比如,有一个用于通知搜索引擎进行职位索引更新的消息队列,消息内容就是职位主键positionId,当职位数据更新频繁的时候,在队列中积累了100个消息,其中有30个消息都是关于同一个职位A的。那么,我的需求就是如何在这些消息被消费前,将其根据职位主键进行去重,也就是说,职位A的索引更新,我只想执行一次,而不是30次。我之所以把这个需求称为伪需求,因为队列本身就是为了有序进行任务的一个数据结构,即先进先出。而经过去重,本质上就是对于同一个主键,都只执行一次,因此顺序是不能严格保证的,不过在主键上还是保留了大方向上的有序性。即使是伪需求,对于我们目前的情况来说,还是很有必要的。 需求针对的数据范围从目前的索引更新日志分析看来,任务高峰时期,在几十毫秒内会有十来个相同的消息(每个消息都是一批职位主键)连续从队列中被消费。我自己定义的数据范围的概念就是:当队列中消息积累的某个时刻,针对这些积累的数据进行去重,这些积累的数据就是数据范围,这是一个动态的数据范围。每当进来一个消息,就会针对当前的数据范围进行去重,保证当前数据范围不会存在重复数据。发生这种重复的现实原因就是,索引更新队列的通知服务是开放的,公司内部很多其他服务都会通知搜索引擎进行数据更新。比如职位服务在发布、更新职位时,算法服务在进行职位匹配后,数据统计服务在统计职位数据后等等。而且很多时候,由于功能的先后接入以及缺乏相关良好的规划,甚至会出现一些重复通知的情况,在一个调用链中,上下游可能会重复通知索引更新队列

    队列   rabbitmq   Spring   过滤器   2019-10-18 浏览(283) 阅读原文>>
  • 局域网域名解析服务配置——BIND域名解析

    已经很久没更新博客了,最近在忙公司“上云”的项目,也就是将应用从自有IDC机房迁移到阿里云上。于是乎,服务器相关配置的任务都落到我头上了:+ 服务器hostname设置+ 搭建内网域名解析服务 + 服务器nameserver配置 BIND BIND(Berkeley Internet Name Domain)是现今互联网上最常使用的DNS软件,使用BIND作为服务器软件的DNS服务器约占所有DNS服务器的九成。BIND现在由互联网系统协会(Internet Systems Consortium)负责开发与维护。 安装BIND服务在事先准备好的DNS服务器A(IP地址是172.16.1.1)上,通过命令来安装BIND服务:bashyum install bind.x8664 -y安装成功之后,可以通过命令查看关于BIND服务的文件目录:bash[root@dns-server etc] rpm -ql bind/etc/logrotate.d/named/etc/named/etc/named.conf/etc/named.iscdlv.key/etc/named.rfc1912.zones/etc/named.root.key/etc/rndc.conf/etc/rndc.key/usr/sbin/named/usr/sbin/named-checkconf/usr/sbin/named-checkzone/usr/sbin/named-compilezone/usr/sbin/named-journalprint/var/named/var/named/data/var/named/dynamic/var/named/named.ca/var/named/named.empty/var/named/named.localhost/var/named/named.loopback/var/named/slaves[root@dns-server etc]+ /etc/named.conf:bind的主配置文件+ /etc/named.rfc1912.zones:定义域名空间解析明细的文件+ /usr/sbin/named-checkconf:检测/etc/named.conf文件语法+ /usr/sbin/named-checkzone:检测zone和对应zone文件的语法 named.conf配置bash[root@dns-server etc] more named.conf//// named.conf//// Provided by Red Hat bind package to configure the ISC BIND named(8) DNS// ser

    DNS   BIND   域名解析   named   2019-09-09 浏览(358) 阅读原文>>
  • 开发一个简单的集成编译、打包、服务检测、依赖发布的模块

    什么是持续集成 持续集成是一种软件开发实践,即团队开发成员经常集成他们的工作,通常每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。 大师Martin Fowler对持续集成是这样定义的:持续集成是一种软件开发实践,即团队开发成员经常集成他们的工作,通常每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽快地发现集成错误。许多团队发现这个过程可以大大减少集成的问题,让团队能够更快的开发内聚的软件。 减少风险 一天中进行多次的集成,并做了相应的测试,这样有利于检查缺陷,了解软件的健康状况,减少假定。 减少重复过程 减少重复的过程可以节省时间、费用和工作量。说起来简单,做起来难。这些浪费时间的重复劳动可能在我们的项目活动的任何一个环节发生,包括代码编译、数据库集成、测试、审查、部署及反馈。通过自动化的持续集成可以将这些重复的动作都变成自动化的,无需太多人工干预,让人们的时间更多的投入到动脑筋的、更高价值的事情上。 任何时间、任何地点生成可部署的软件 持续集成可以让您在任何时间发布可以部署的软件。从外界来看,这是持续集成最明显的好处,我们可以对改进软件品质和减少风险说起来滔滔不绝,但对于客户来说,可以部署的软件产品是最实际的资产。利用持续集成,您可以经常对源代码进行一些小改动,并将这些改动和其他的代码进行集成。如果出现问题,项目成员马上就会被通知到,问题会第一时间被修复。不采用持续集成的情况下,这些问题有可能到交付前的集成测试的时候

    集成发布   Shell   服务监控   2019-06-09 浏览(431) 阅读原文>>
  • 搜索引擎进阶——关键字预处理模块

    前言在搜索引擎的两个阶段会用到分词功能,分别是索引和查询。先说一下个人在垂直搜索引擎常用的索引分词设置(针对IK分词器)。无论采用何种分词设置,都会有一定的局限性或者说缺陷。因此在合适的阶段选择适合业务场景的分词方式才是最重要的。 索引阶段IK分词器提供了两种分词模式,通过布尔变量useSmart来设置。我在索引阶段设置useSmartfalse,其含义就是采用最小粒度分词,即会分出最多的可能的词汇(包括分词歧义词汇)。比如短语“中华人民共和国”的分词结果就是:中华人民共和国、中华人民、中华、华人、人民共和国、人民、共和国、共和、国。可以看出来,这个模式下分词器会将词库中有的词全部分出来。其中“华人”这个词在短语中属于歧义词,在这个语境中是不合适的。之所以选择这个模式,是因为在索引的时候尽可能的建立更多分词的倒排索引关系链,这与全文检索的“一次索引,多次查询”的特点有关。对于这个短语来说,除了“华人”之外的其它分词能搜索到这个短语,都是合理的场景。 查询阶段我在查询阶段(也就是用户输入关键字查询结果中的分词阶段),设置了useSmarttrue。其含义是IK分词器会用其智能分词功能给你最合适的分词结果,一般来说是词语最少的结果,但是它能最大程度保留原短语的语境含义。比如短语“中华人民共和国”的分词结果就是:中华、人民共和国。这两个词就最大程度保留了语境含义,而且其输入能完美映射到索引阶段。对于,索引中出现“中华”和“人民共和国”两个词语相距很远的情况,可以通过设置查询跨度来过滤。"中华人民共和国"~2,这里的2是指两个双引号之间的短语,各个分词的起始位置之间的最大允许间隔。 在Solr的schema.xml的配置xml

    Solr   Java   分词   字典树   搜索引擎   2019-07-24 浏览(356) 阅读原文>>
  • 搜索引擎入门——solr筛选器facet的应用

    前言 搜索引擎的出现,整合了众多网站信息,恰恰起到了信息导航的作用。通用搜索引擎就如同互联网第一次出现的门户网站一样,大量的信息整合导航,极快的查询,将所有网站上的信息整理在一个平台上供网民使用,于是信息的价值第一次普遍的被众多商家认可,迅速成为互联网中最有价值的领域。互联网的低谷由此演变为第二次高峰。大家熟知的搜索引擎Google、百度、雅虎等是通用搜索引擎现如今的杰出代表,他们为互联网的发展做出了重要的贡献。然而,搜索引擎行业也不是一家公司就可以独撑天下的,从百度的上市、yahoo中国的并购一系列动作表明,如今的搜索引擎大战如同门户网站初期的竞争一样激烈。相信,通用搜索引擎在经历过一段时间的角逐后,也将会继续维持几大服务商各自分控一部分市场的局面。通用搜索引擎的性质,决定了其不能满足特殊领域、特殊人群的精准化信息需求服务。市场需求多元化决定了搜索引擎的服务模式必将出现细分,针对不同行业提供更加精确的行业服务模式。可以说通用搜索引擎的发展为垂直搜索引擎的出现提供了良好的市场空间,势必将出现垂直搜索引擎在互联网中占据部分市场的趋势,也是搜索引擎行业细分化的必然趋势。 垂直搜索引擎是针对某一个行业的专业搜索引擎,是搜索引擎的细分和延伸,是对网页库中的某类专门的信息进行一次整合,定向分字段抽取出需要的数据进行处理后再以某种形式返回给用户。垂直搜索是相对通用搜索引擎的信息量大、查询不准确、深度不够等提出来的新的搜索引擎服务模式,通过针对某一特定领域、某一特定人群或某一特定需求提供的有一定价值的信息和相关服务。其特点就是“专、精、深”,且具有行业色彩,相比较通用搜索引擎的海量信息无序化,垂直搜索引

    Solr   Facet   Java   搜索引擎   2019-05-06 浏览(607) 阅读原文>>
  • 微信小程序深入踩坑总结

    一、小程序页面栈 wx.navigateTo(Object object)这是小程序中最常用的页面跳转方法,功能有点类似于HTML中的link,在参数url中可以跟参数,其方式也与href类似。官方是这样描述的: 保留当前页面,跳转到应用内的某个页面。但是不能跳到tabbar页面。使用wx.navigateBack可以返回到原页面,小程序中页面栈最多十层。这个方法实际上会在页面栈保留当前页,然后新页面也会入栈,所以一直使用wx.navigateTo进行页面跳转,页面栈很容易就达到十层的限制,然后就再也无法进行页面跳转了。![图片](https://oomabc.com/staticsrc/img/201901/31/1548927005955fb2a3f87642749788f78b7bd869edce5.jpg) wx.redirectTo(Object object)这时候,我们可以使用wx.redirectTo进行页面跳转,它会将当前页面弹出页面栈,然后新的页面入栈。官方文档: 关闭当前页面,跳转到应用内的某个页面。但是不允许跳转到tabbar页面。如果页面跳转都是通过这个方法实现,页面栈就不会满,也就不会出现无法跳转的情况。但是问题来了,使用这个方法是无法回到上一页的,因为你根本就没有在页面栈保存上一页的信息,显然这不是我们想要的。 wx.reLaunch(Object object)先来看官方的描述: 关闭所有页面,打开到应用内的某个页面。显然,这个方法先重置页面栈,然后将新页面入栈。不过,如果一直使用这个方法进行页面跳转,跟一直用wx.redirectTo带来的问题是一样的:无法返回上一页。 取长补短上面提到的几种页面跳转方式各有所长,不过好在他们的参数传递方式以及回调函数都是一致的。因此,我们根据实际的业务逻辑和页面跳转关系进行分类,然后将流程递进式跳转使用wx.redirectTo,流程重置式跳转使用wx.reLaunch。这样一来既保证了页面跳

    小程序   分享   小程序拉起   登录   2019-01-31 浏览(2821) 阅读原文>>
  • 搜索引擎进阶——solr自定义function

    本章要介绍的内容是solr中的自定义排序规则,或者说自定义得分函数。看懂本章内容,最好了解过以下知识点:1. solr的基本查询功能2. solr的edismax高级复合查询3. edismax中bf的作用关于solr内置function的用法可以参考官方文档《[Function Queries][solrLink]》,后续如果有机会,我会另出一篇文章加以阐述。---- 需求背景本来搜索服务提供的是一个职位搜索功能,面向的用户是猎头。所以,有一个需求就是按照猎头对每个职位的一个偏好预测值(记为V)进行职位综合排序。每个猎头对于不同的职位都有一个偏好预测值,记为H1V1。这个值由AI团队根据猎头所有行为记录进行统计计算,然后搜索团队要在猎头某一次搜索的结果内进行偏好预测值排序。几万猎头和几万职位的预测值是一个非常庞大的数据集。功能实现方式:1. 在职位索引增加一个动态字段,然后在建索引的时候猎头ID命名动态字段,对应的值就是这个猎头对当前职位的偏好预测值。dmdouble10002100,表示猎头10002对当前职位的偏好预测值为100。然后在搜索的时候,通过猎头id指定字段进行sort即可。2. 自定义一个function,通过solr提供的功能,在搜索时进行实时预测值查询,然后内置排序。方法1确实是一个最简单的方式,非常好理解,就是增加一个动态排序字段,然后sort即可。但是问题是数据量会非常大,而且意义不大。如果有10000个职位,30000个猎头,那么笛卡尔积就是3亿的偏好预测值,平均每个职位上要大约增加30000个动态字段,一个document会变得非常臃肿。当然,可以进行无效数据的预处理等方式进行优化,但是最后的数据依旧会庞大无比,关键是大部分都是无效数据。所以,我采用的是方法2。![图片](https://oomabc.com/staticsrc/img/201812/18/15

    ValueSource   排序   Solr   Java   搜索引擎   2019-07-23 浏览(1487) 阅读原文>>
  • springMVC中controller参数拦截问题处理

    在一个安静的清晨,我正看着自己的代码思考人生。突然,下方的通讯工具一阵抖动。这么早,谁会找我?点开消息框一看,一种“不翔”的预感用上心头——来活了。原来是网安发来的一份网站漏洞扫描报告,大意就是我们主站存在高等风险弱点若干个,主要就是XSS漏洞和Http未加密传输,以及列出了相关解决方案。Http未加密的解决方式是通过代理重定向到Https,这个我知道,但是,这XSS是什么东东?之前听过这个词,但不太清楚实际意思,于是Google了一下: 跨站脚本(英语:Cross-site scripting,通常简称为:XSS)是一种网站应用程序的安全漏洞攻击,是代码注入的一种。它允许恶意用户将代码注入到网页上,其他用户在观看网页时就会受到影响。这类攻击通常包含了HTML以及用户端脚本语言。 XSS攻击通常指的是通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。这些恶意网页程序通常是JavaScript,但实际上也可以包括Java,VBScript,ActiveX,Flash或者甚至是普通的HTML。攻击成功后,攻击者可能得到更高的权限(如执行一些操作)、私密网页内容、会话和cookie等各种内容。关于XSS的详细介绍我这里就不进行阐述了,因为本人也不是很清楚,可以参考美团技术团队的一篇文章:[前端安全系列(一):如何防止XSS攻击?] [outLink]。接下来,我主要阐述如果在springMVC中进行请求参数拦截和XSS转义处理的。---考虑到,我们需要在参数传到controller之前就要处理参数,因此需要在某个拦截器中将HttpServletRequest对象进行处理。拦截器处理有两种比较常用的:1. mvc:interceptors配置MVC拦截器:继承org.springframework.web.servlet.handler.HandlerI

    springMVC   ModelAttribute   拦截器   2018-12-14 浏览(3019) 阅读原文>>
  • 从零开发参数同步框架(六)—— 简版配置中心

    零、前言前面五章已经详细介绍了如何从零开始开发一个参数同步框架。如果按照前面五章一步一步实践,应该是可以成功开发出一个可投入使用的框架的。如果不行,那应该是文章文字组织的问题了,没有将很多内容描述的通俗易懂。我们抽时间从头读一遍每一篇文章,争取逐步修改、统一名词、理清逻辑,各位海涵。 一、关于配置中心本文中定义:将那些公共配置信息统一推送到zk节点,需要使用的客户端按需加载即可。公共配置:所有客户端都会使用的、并且其值都是一致的。例如:1. mySQL数据库连接信息:url、driverClass、username、password。shelljdbc.oneblog.urljdbc:mysql://192.168.1.1:3306/oneblog?useUnicodetrue&characterEncodingUTF-8&autoReconnecttruejdbc.oneblog.usernametestjdbc.oneblog.passwordtest2. redis配置信息:host、port。shellredis.host192.168.1.2redis.port63793. zookeeper配置信息:host:port。shellzk1.address192.168.1.101:2181,192.168.1.102:2181,192.168.1.103:21814. hessian服务地址:host:port/service。Properties 账户服务auth.remote.urlhttp://192.168.1.4:8680/remote 文件服务file.remote.urlhttp://192.168.1.5:8028/remote 文章服务article.remote.urlhttp://192.168.1.6:8780/remote5. mongodb配置信息:hostport、username、password、db。shellmongo.hostportmongo.uat.com:27017mongo.usernameoneblogmongo.password123456mongo.dboneblog 以上需要存放在配置中心,以下是各个客户端根据实际负载选择的个性化参数,不必放在配置中心mongo.connectionsPerHost10mongo.threadsAllowedToBlockForConnectionMultiplier5mongo.connectTimeout10000mongo.maxW

    参数同步   2019-02-21 浏览(2233) 阅读原文>>
  • 从零开发参数同步框架(五)—— Spring集成

    前面几章详细介绍了这个参数同步框架代码中的工具类、服务端、客户端等代码以及相关解释。不过由于个人的语言组织能力比较弱,可能写的比较乱,部分名词容易混淆,还请各位看官连看带猜吧。截止到上一章为止,参数同步框架以及可以投入生产使用了。只是不管是客户端还是服务端的项目,都需要在web项目启动之后,手动调用一遍zk连接初始化的代码。我们回顾一下服务端初始化:java Object zkHostString props.get("ggframework.zookeeper"); //直接指定zookeeper地址 if(zkHostString ! null && String.valueOf(zkHostString).length() 0) { GgFrameworkUtil.initCuratorFramework(String.valueOf(zkHostString)); } else { //从默认配置文件加载 GgFrameworkUtil.initCuratorFramework(); }客户端初始化:java //初始化zk连接 GgFrameworkUtil.initCuratorFramework(); //创建连接池 ExecutorService pool Executors.newCachedThreadPool(); //创建需要监听的信息,这里是按约定的库和表 GgTable table new GgTable(); table.setDb("searchmanager"); table.setTable("tbmgrparameters"); try { //添加监听节点信息 GgFrameworkClient.listener(table, new IChangedService() { @Override public void excute(GgTable table) { cacheService.loadPortraitParameters(); } }, pool); } catch (Exception e) { e.printStackTrace(); }从上面的代码中不难看出,服务端和客户端都有相同的代码,那就是初始化zk连接:GgFrameworkUtil.initCuratorFr

    参数同步   Spring   2018-10-30 浏览(2157) 阅读原文>>
  • 从零开发参数同步框架(四)—— 客户端编码

    客户端框架的客户端代码完成的主要功能分为以下几个方面:1. 初始化zk连接(initClient):根据默认或者指定的zk集群地址,创建一个Curator维护的zk连接对象。2. 添加节点监听(listener):根据指定的数据库+数据表,在zk上创建对应的节点,并添加监听事件。特别地,如果调用该方法的时候客户端已完成zk连接的初始化,则直接调用addListenerToNode方法,为实际zk节点添加监听事件,否则会将节点信息暂存在内存中,等待zk连接完成之后回调addListenerFromCache方法3. 给节点添加监听事件(addListenerToNode):为实际的zk节点(与listener方法添加的数据库、数据表关联)添加监听事件,当这个节点(本系列文章中的参数表,即服务端管理的配置持久化表)的数据发生变更,会在当前客户端上触发刚刚添加的监听事件。4. 根据缓存给节点添加监听事件(addListenerFromCache):根据内存中所有节点信息,通过调用addListenerToNode方法,为每个节点创建监听事件。然后从内存删除已创建事件的节点信息。5. 释放节点的监听事件(releaseListener):删除已创建事件的节点上的监听事件。--- 客户端功能详解 初始化zk连接这个比较简单,直接调用之前介绍的工具类即可:java //初始化连接zookeeper public static void initClient(String zkHost) { if(StringUtils.isBlank(zkHost)) { GgFrameworkUtil.initCuratorFramework(); } else { GgFrameworkUtil.initCuratorFramework(zkHost); } } 添加节点监听这个方法有三个参数: GgTable:维护这个节点的监听目标,指定数据库、数据表即可。 IChangedService:这个接口就是当GgTable对应节点信息发生变动,即服

    参数同步   2018-10-27 浏览(1393) 阅读原文>>
  • 从零开发参数同步框架(三)—— 服务端编码

    服务端功能仅就框架而言,服务端(GgFrameworkServer)代码的功能只有一个,向客户端发送(方法是:broadcast(GgTable table))某个数据发生变动的信息。注意:这里服务端提供的broadcast方法不会指定通知哪个客户端,只会通知参数对应的节点,这样就达到与客户端解耦的目的。客户端也无需知道谁是服务端,它只要告诉zookeeper自己想要监听的参数信息即可。不过,作为一个完整的参数同步框架,其服务端还需要提供完整的如下功能:1. 参数管理:这是一个可视化界面,方便用户进行参数查询、分组查询、参数权限控制等。2. 修改日志:记录每一个参数的详细修改记录,包括参数初始导入信息、修改信息。信息包含时间、当时值、修改之后的值。3. 变动通知:当参数发生变动时,需要服务端通过框架代码提供的功能(GgFrameworkServer.broadcast),向客户端发送变动通知同时传递约定好的数据(本框架中就是GgTable)。4. 参数查询:当客户端接到变动通知后,将会通过这个接口从服务端查询参数的最新值。这是一个dubbo接口,因此服务端和客户端同样也无需知晓对方的地址,可以解耦。接口接收的主要参数是客户端指定的参数key列表。--- 服务端初始化在web项目启动之后,调用GgFrameworkUtil.initCuratorFramework方法既可以初始化对zookeeper的连接:java Object zkHostString props.get("ggframework.zookeeper"); //直接指定zookeeper地址 if(zkHostString ! null && String.valueOf(zkHostString).length() 0) { GgFrameworkUtil.initCuratorFramework(String.valueOf(zkHostString)); } else { //从默认配置文件加载 GgFrameworkUtil.initCuratorFramework(); }项目启动

    参数同步   2019-02-20 浏览(2418) 阅读原文>>
  • 从零开发参数同步框架(二)—— 前期准备之工具类

    零、基础定义 约定本框架对与监听参数的设计功能是通用的,它维护一个监听的数据节点信息,包含监听的db、table以及id信息。在zookeeper上,创建一个广播节点(broadcasetnode)作为根节点;在根节点下的目录结构是/broadcasetnode/db/table/id,每个客户端可以监听对应的节点以获取不同范围的触发事件。 GgTable当平台管理的参数发生变动时,服务端代码会将该对象传递给zk节点,然后通过监听事件传递给对应的客户端。它保存了监听的详情,包括监听的数据库、数据表、数据字段。框架默认实现的功能是触发table级别的事件,另外两个级别需要大家自行实现,比较简单。javaimport java.io.Serializable;public class GgTable implements Serializable { private static final long serialVersionUID 5755663143906038786L; //数据库 private String db; //表 private String table; //默认的id主键值,long型 private Long id; //自定义字段名 private String field; //field 相对于 数据记录的 value值 private Object value; public GgTable(String db, String table) { super(); this.db db; this.table table; } //get、set、equals、toString等方法省略} Curator实例缓存CuratorFrameworkUtil工具类对Curator实例对象CuratorFramework进行了缓存,缓存的Key就是zk地址,它负责创建最简洁的连接对象并复用。这个简洁的对象与框架路径无关。javapublic class CuratorFrameworkUtil extends GgFrameworkAbstract { private static final String LOGPREV "[CuratorFrameworkUtil] "; //注册zk地址,命名前缀解析 private static final String PREFIX "://"; //zk连接客户端

    参数同步   Curator   2018-10-24 浏览(3788) 阅读原文>>
  • 1  2 
    blogTest
    分享文章
     
    使用APP的"扫一扫"功能,扫描左边的二维码,即可将网页分享给别人。
    你也可以扫描右边本博客的小程序二维码,实时关注最新文章。