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

  • Java网络编程之Netty学习(二)—— 简单RPC实现

    前言本章实现一个最简单的RPC小工具,简单的不能称之为框架。它是在学习Netty框架时的一个简单应用,包含的常规知识点有动态代理、可重入锁、Java反射、序列化。+ 动态代理 根据接口定义,生成一个该接口的一个实现对象,这是一个代理对象。在消费者调用接口的某个方法的时候,我们可以在方法前后增加自定义逻辑。本例中,增加的逻辑就是封装接口信息、方法以及参数信息,然后通过RPC服务类将封装的好的信息传递给生产者,然后将返回结果返回给消费者,完成一个RPC调用过程。+ 可重入锁 通过ReentrantLock以及它的Condition属性对象来实现将Netty的NIO特性转为常规RPC的同步性。 ReentrantLock是一个可重入锁,它与在方法或者代码块上使用synchronized具有相同的并发特性和隐性监视器锁访问语义,不过,它具有更好的扩展性。这个锁被最后获得且未释放它的线程所拥有,一个线程如果尝试去获得一个未被任何线程拥有或者已被自己拥有的锁,都会立即成功。 关于synchronized的隐性监视器锁(参考其它文章): + 同步方法通过ACCSYNCHRONIZED关键字隐式的对方法进行加锁。当线程要执行的方法被标注上ACCSYNCHRONIZED时,需要先获得锁才能执行该方法。 + 同步代码块通过monitorenter和monitorexit执行来进行加锁。当线程执行到monitorenter的时候要先获得所锁,才能执行后面的方法。当线程执行到monitorexit的时候则要释放锁。 + 每个对象自身维护这一个被加锁次数的计数器,当计数器数字为0时表示可以被任意线程获得锁。当计数器不为0时,只有获得锁的线程才能再次获得锁,所以synchronized也是可重入锁。+ Java反射 Java反射机制可以让我们在编译期(Compile Time)之外的运行期(Runtime)获得任何一个类的字

    Netty   Java   RPC   2019-05-06 浏览(1534) 阅读原文>>
  • Java网络编程之Netty框架学习(一)

    零、前言Netty致力于成为一个异步的事件驱动的网络应用框架,同时,它也是NIO(非阻塞IO)的。通过它,程序员可以简单快速开发出一种可维护、易扩展且高性能的服务端-客户端通信协议。它通极大的简化了连接激活、消息发送、消息接收等环节,通过在这些环节添加事件监听从而将网络编程退化为流式处理,也就是说,对于普通开发者可忽略这些环节的细节和异步性(实际上每个环节的动作都是异步的),我们可以专注各个环节需要处理的业务逻辑。比如基于UPD、TCP的Socket通信服务开发。简单快速并不意味着放弃了维护性和高性能表现。得益于在像FTP、SMTP、HTTP以及其他二进制协议或者更老的一些基于文本的协议丰富的开发实践经验,Netty团队成功的设计了一种方式,可以同时兼顾易开发、高性能、稳定性和易扩展等方面。Netty的设计哲学让它在众多的网络通信框架中显得与众不同。无论是阅读API文档还是通过它来编程,你都能感受到Netty给你带来的舒适体验,它只可意会不可言传的设计哲学让你今后的编程生涯变得更加简单有趣。上面关于Netty的描述都是我根据官网([https://netty.io/wiki/user-guide-for-4.x.html] [nettyHome])瞎翻译的,看看就好了。![图片](https://oomabc.com/staticsrc/img/201811/18/1542524873785d96497fd31934e61923771fbc6aa5c5a.jpg)---- 一、开始前的准备有兴趣看到这里的,我相信你一定是“精通”java开发的码农,那么此时你拥有的JDK版本一定不低于1.6吧,那就ok了。同时,本例的项目是一个maven项目,因此我一起给出相关依赖:xml io.netty netty-buffer 4.1.16.Final io.netty netty-all 4.1.16.Final io.netty netty-transport-native-epoll 4.1.16.Final----- 二、Let's Do IT为

    网络编程   Java   Netty   2019-05-06 浏览(1642) 阅读原文>>
  • Mac OS下安装Homebrew以及mysql重置root密码

    homebrew   mysql   root   2019-02-21 浏览(1467) 阅读原文>>
  • 从零开发参数同步框架(六)—— 简版配置中心

    零、前言前面五章已经详细介绍了如何从零开始开发一个参数同步框架。如果按照前面五章一步一步实践,应该是可以成功开发出一个可投入使用的框架的。如果不行,那应该是文章文字组织的问题了,没有将很多内容描述的通俗易懂。我们抽时间从头读一遍每一篇文章,争取逐步修改、统一名词、理清逻辑,各位海涵。 一、关于配置中心本文中定义:将那些公共配置信息统一推送到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 浏览(2173) 阅读原文>>
  • 从零开发参数同步框架(五)—— 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 浏览(2101) 阅读原文>>
  • 从零开发参数同步框架(四)—— 客户端编码

    客户端框架的客户端代码完成的主要功能分为以下几个方面: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 浏览(1339) 阅读原文>>
  • 从零开发参数同步框架(三)—— 服务端编码

    服务端功能仅就框架而言,服务端(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 浏览(2362) 阅读原文>>
  • 从零开发参数同步框架(二)—— 前期准备之工具类

    零、基础定义 约定本框架对与监听参数的设计功能是通用的,它维护一个监听的数据节点信息,包含监听的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 浏览(3720) 阅读原文>>
  • 从零开发参数同步框架(一)—— 项目起源

    前言从事Java开发已经有八个多年头了,从开始参加工作,就一直自诩热爱技术、喜欢钻研、喜欢写代码。三年前,我开始意识到,自己也并没有哪一个方面的技术达到足够的深度,甚至技术广度也远远不足。所以,从那时开始,有意识的折腾一些整体性的应用,俗称造轮子。三年前,我刚好从工作了四年多的爱裳邦购离职加入了现在这家公司——猎上网。新公司接触的项目确实比较多,加上一年后升职为后端技术经理,接触并负责公司所有的后端项目。当时,公司处于一个高速发展的阶段,所以很多基础建设不是很全面,整个技术部门都是以快速支撑为目的。当时公司很多项目已经开始服务化部署,因此项目划分很细,不同的项目大概有20来个,线上的容灾部署约有60台虚拟机。加上,公司业务发展迅速,各种活动、产品迭代频繁,而当时项目参数配置还是传统的resource.properties方式。所以矛盾很明显,这种参数配置方式需要重启项目才能使更改之后的值生效,而且几十台项目的参数无法集中管理。于是,能够集中化管理所有项目参数并实时推送的一个框架/平台对我们来说就显得非常重要和必须了。原谅我当时孤陋寡闻,并没有接触过阿波罗这个框架,加上一些的小自私(锻炼下技术),我决定自己利用闲暇时间,研发一个适用于公司的参数同步框架。--- 设计思路通过一个中心化数据管理平台,集中管理所有项目的配置参数,尤其是需要实时动态管理的那些。定义:参数管理平台称为服务端,所有接入平台的项目称为客户端。它有以下功能:1. 所有参数可以按照项目、描述等信息进行管理和查询。2. 所有参数支持动态修改,并由平台实时推送到那些使用它的服务器上。3. 所有参数都保留完整的修改历史,方便回退。4. 所有参数都以字符串形式存

    参数同步   zookeeper   2018-10-22 浏览(2787) 阅读原文>>
  • SpringBoot2从零开始(三)—— rabbit MQ

    RabbitMQ是流行的开源消息队列系统,用erlang语言开发。RabbitMQ是AMQP(高级消息队列协议)的标准实现。如果不熟悉AMQP,直接看RabbitMQ的文档会比较困难。不过它也只有几个关键概念,这里简单介绍。几个概念说明: + Broker:简单来说就是消息队列服务器实体。 + Exchange:消息交换机,它指定消息按什么规则,路由到哪个队列。 + Queue:消息队列载体,每个消息都会被投入到一个或多个队列。 + Binding:绑定,它的作用就是把exchange和queue按照路由规则绑定起来。 + Routing Key:路由关键字,exchange根据这个关键字进行消息投递。 + vhost:虚拟主机,一个broker里可以开设多个vhost,用作不同用户的权限分离。 + producer:消息生产者,就是投递消息的程序。 + consumer:消息消费者,就是接受消息的程序。 + channel:消息通道,在客户端的每个连接里,可建立多个channel,每个channel代表一个会话任务。消息队列的使用过程大概如下: 1. 客户端连接到消息队列服务器,打开一个channel。 2. 客户端声明一个exchange,并设置相关属性。 3. 客户端声明一个queue,并设置相关属性。 4. 客户端使用routing key,在exchange和queue之间建立好绑定关系。 5. 客户端投递消息到exchange。 exchange接收到消息后,就根据消息的key和已经设置的binding,进行消息路由,将消息投递到一个或多个队列里。 exchange也有几个类型,完全根据key进行投递的叫做Direct交换机,例如,绑定时设置了routing key为abc,那么客户端提交的消息,只有设置了key为abc的才会投递到队列。对key进行模式匹配后进行投递的叫做Topic交换机,符号匹配一个或多个词,符号匹配正好一个词。例如abc.匹配abc.def.ghi,abc.只匹配abc.d

    rabbitmq   SpringBoot   2019-04-26 浏览(1364) 阅读原文>>
  • Linux之相关工程化应用遇到的问题

    ssh免登陆 Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和UNIX的多用户、多任务、支持多线程和多CPU的操作系统。它能运行主要的UNIX工具软件、应用程序和网络协议。它支持32位和64位硬件。Linux继承了Unix以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统。 相关默认:1. .ssh的默认路径为:/root/.ssh2. 公钥、私钥、authorizedkeys、knowhosts等文件在该目录下3. .ssh文件夹的权限为 777 4. authorizedkeys 的权限为 6005. 通过命令chmod 666 ./authorizedkeys,给authorizedkeys设置权限--- WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! 本服务器记为A,目标服务器192.168.100.184记为B。在A服务器执行ssh 192.168.100.184,报错如下:bash[root@zabbix .ssh] ssh 192.168.100.184@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!Someone could be eavesdropping on you right now (man-in-the-middle attack)!It is also possible that the RSA host key has just been changed.The fingerprint for the RSA key sent by the remote host isb5:de:af:87:5d:03:44:92:af:98:de:48:a2:81:df:dd.Please contact your system administrator.Add correct host key in /root/.ssh/knownhosts to get rid of this message.Offending key in /root/.ssh/knownhosts:290RSA host key for 192.168.100.184 has changed and you have requested strict checking.Host key

    linux   ssh   免登陆   2019-09-16 浏览(2799) 阅读原文>>
  • Maven项目一键打包、上传、重启服务器

    Maven+Git项目在本地开发完成之后,发布到目标服务器的方式有多种。如果是企业内部的项目,通常是如下的开发发布流程:1. 工程师本地开发调试通过,提交代码到Git仓库。2. 在集成发布环境的服务器上部署Git环境,通过在发布机上执行获取最新代码、编译打包、发布包、重启目标服务器的流程来实现一键部署。3. 常用的集成发布环境有Jenkins、Hudson。如果是个人项目,比如本项目,那么我并不想在服务器上部署一个Git环境,跟不想再部署一个Jenkins。但是我还是想实现一键发布,怎么办?Maven插件来帮你。 零、修改Maven的setting.xml配置文件1. 打开eclipse对应的maven配置文件setting.xml![图片](https://oomabc.com/staticsrc/img/201810/17/1539740596458cbd1073858624189ad69ac1fbfc15f98.jpg)2. 在servers下增加一个server配置![图片](https://oomabc.com/staticsrc/img/201810/17/153974062295892a8257754f648a5868810dbd7d5fea8.jpg)--- 一、增加maven依赖1. pom.xml的build下增加wagon-ssh配置:xml org.apache.maven.wagon wagon-ssh 2.8 2. 在plugins下增加一个插件配置:xml org.codehaus.mojo wagon-maven-plugin 1.0 com.jcraft jsch 0.1.54 org.bouncycastle bcprov-jdk16 1.46 oneblogServer target/ROOT.war scp://47.99.82.106/mnt/ sh /opt/restarttomcat.sh true --- 二、增加maven打包发布命令1. 在web项目上右键 Run as Maven build...2. 在弹出的窗口上,Goals一栏填入install package -Pprod wagon:upload-single wagon:sshexec![图片](https://oomabc.com/staticsrc/img/201810/17/153974065716583d837b8ae304934

    maven   ssh   一键发布   2018-10-17 浏览(2951) 阅读原文>>
  • Nginx的nginx.conf配置部分解释

    百度百科: Nginx (engine x) 是一个高性能的HTTP和反向代理服务,也是一个IMAP/POP3/SMTP服务。Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文:Рамблер)开发的,第一个公开版本0.1.0发布于2004年10月4日。其将源代码以类BSD许可证的形式发布,因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。2011年6月1日,nginx 1.0.4发布。Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。![图片](https://oomabc.com/staticsrc/img/201810/17/1539741188800b0a0cb1f3f1345a7b6304781ebd1b001.jpg) -------- 下面是个人收集的一些比较常用的Nginx配置项以及相关解释,仅供参考:Nginxuser nobody; 定义Nginx运行的用户和用户组workerprocesses 4; nginx进程数,建议设置为等于CPU总核心数 workerrlimitnofile 655350; 工作模式与连接数上限:workerconnections是单个后台worker process进程的最大并发链接数,并发总数是 workerprocesses 和 workerconnections 的乘积, 即 maxclients workerprocesses workerconnectionsevents { workerconnections 15024;} http { include mime.types; 文件扩展名与文件类型映射表 defaulttype application/octet-stream; 默认文件类型 logformat main '$remoteaddr - $remoteuser [$timelocal] "$request" ' '$status $

    nginx   conf   2018-10-17 浏览(3384) 阅读原文>>
  • Eclipse相关使用问题记录

    eclipse   maven   2018-10-18 浏览(2523) 阅读原文>>
  • MongoDB关于authSchema的认证版本问题

    AuthenticationFailed MONGODB-CR credentialsmongoDB 3.0以上版本,服务端默认的账号认证方式是「SCRAM-SHA-1」,对应认证版本是5.0。而目前一般的mongoDB客户端,包括mongoBooster、mongoVUE或者Robomongo一般还是3.0版本的「MONGODB-CR」,还有我们java驱动中使用的一般也还有3.0版本的认证方式,所以客户端连接或者启动项目会报类似的错误:shellFailed to authenticate root@admin with mechanism MONGODB-CR: AuthenticationFailed MONGODB-CR credentials missing in the user document既然知道这个错误信息是由客户端与服务端的认证方式差异造成的,那么我们需要修改服务端的默认认证版本即可。--- 查看服务端认证版本在服务器通过mongo host:port/db -u root -p pwd方式登陆shell命令窗口,然后在admin库查看当前的认证版本。bash db.system.version.findOne({id:'authSchema'});得到信息如下:bash { "id" : "authSchema", "currentVersion" : 5 }--- 修改currentVersion 如果当前是replSet模式,建议先切换为master/slave模式本文章的例子中,使用的mognodb配置文件如下:bashbindip 0.0.0.0dbpath /home/mongodb/repDatalogpath /home/mongodb/log/mongodb.loglogappend trueport 27017fork trueauth true用于主从、副本集之间的鉴权keyFile /home/mongodb/conf/key directoryperdb truemaxConns2000httpinterface truereplSet replSetTestmaster true1. 以管理员登陆数据库,删除所有用户信息。bash { "id" : "authSchema", "currentVersion" : 5 }2. 修改auth false,重启mongod。3. 登陆无账号模式,在admin数据库下创建系统权限用户。bash db.createUser({user:"root",pwd:"1

    mongoDB   认证   authSchema      2019-07-12 浏览(2408) 阅读原文>>
  • 1  2  3  4 
    blogTest
    分享文章
     
    使用APP的"扫一扫"功能,扫描左边的二维码,即可将网页分享给别人。
    你也可以扫描右边本博客的小程序二维码,实时关注最新文章。