gradle application plugin 打可执行jar, gradle executable/runnable jar

gradle application plugin 打可执行jar, gradle executable/runnable jar https://docs.gradle.org/current/userguide/application_plugin.html edit build.gradle apply plugin: ‘application’ application { applicationDefaultJvmArgs = ["-Xms512m", “-Xmx1600m”] } mainClassName = “org.gradle.sample.Main” gradle distZip applicationDefaultJvmArgs 用于配置jvm 参数 gradle executable jar, application plugin apply plugin: ‘application’ gradle installApp

2016-01-18 · 1 min · 38 words · -

JDBC 优化

JDBC 优化 http://www.infoq.com/cn/news/2017/03/Analysis-errors-MySQL-JDBC?utm_source=infoq&utm_medium=popular_widget&utm_campaign=popular_content_list&utm_content=homepage 这部分与jdbc无关,是对于MySQL优化的普通技巧 利用查询缓存。不要把函数直接写在sql语句里; 当只需要一条记录时查询加上LIMIT 1; 尽量避免SELECT *这样写; 用连接池; 建索引; 更多关于MySQL的优化 MySQL性能优化的最佳20+条经验 完全优化MySQL数据库性能的八大巧方法 jdbc的优化: 尽量少用元数据方法; 尽量避免null。MySQL中对值为null情况花费更多的空间和处理而加重负担,应该指定专门的值来表示空值,在方法调用时传参也要避免null; 善用哑查询。在仅想得到表信息等而不需要返回记录的情况下,使用"select * from tableName where 1=0"这样的哑查询就能免于遍历; 善用预处理 (PreparedStatement,PreparedCall) 。PreparedStatement不但具有一次编译重复使用的优势,而且因为jdbc默认将参数以字符串形式传给数据库,而用PreparedStatement设参数则可以显式地指定数据类型,避免参数传递和来回转换的负担; Java代码 pstmt=conn.preparedStatement("insert into test_table(……) values(….?)"; [code language=""][/code] pstmt.setString(1,"aaa"; pstmt.addBatch(); pstmt.setString(1,"bbb"); pstmt.addBatch(); ….. pstmt.executeBatch(); 合理选择excute方法,杀鸡就用鸡刀。execute(String sql)方法返回一个boolean值,它执行任意复杂的sql语句,可以产生多个结果集。如果有结果产生返回 true,如果没有结果集产生或仅是一个更新记数则返回 false。它产生的结果集可以通过getResultSet()和getMoreResults()获得,更新记数可通过getUpdateCount()获得。显然execute(String sql)方法的使用要复杂一些,因此如果只是简单的查询或更新操作请使用executeQuery(String sql)和executeUpdate(String sql)方法。executeUpdate(String sql)能执行INSERT,UPDATE,DELETE语句,及DDL和DML命令 (此时返回值为0) ; 批执行更高效。stmt.addBatch(String sql); stmt.executeBatch(); 最好手动提交。不但可以可以保证数据原子性,而且对新能提高留下余地 Java代码 try{ boolean commitStat = connection.getAutoCommit(); connection.setAutoCommit(false); // TODO: 用PreparedStatement 性能比Statementh好. connection.commit(); connection.setAutoCommit(commitStat); } catch(SQLException e){ } finally{ ...

2016-01-15 · 1 min · 118 words · -

cygwin 默认英文环境

cygwin 默认英文环境 搜索结果里充斥着大量让cygwin显示中文的文章以及各种版本转载,我不知道转载这些文章的同学到底自己亲自试验过没有,显示出来的中文往往只显示一半,这样也能算能显示中文了?这么多坑爹的结果,却没有一个告诉大家怎么使用英文界面的方法? 目前的cygwin的shell界面往往是由windows的localization设定决定的,所以如果你将local设定为中国,那么界面默 认都是已经能显示中文的了。但cygwin的中文显示,不但老是出问题,而且也不好看。所以将其界面直接改变成英文,倒也是一个不错的选择之一,只不过这 里提醒大家,你的目录或者文件有很多中文名的,那么最好还是显示中文的比较好,虽然可以让英文shell显示中文,但是显示还是不好看。 让cygwin shell使用英文界面只用在~/.bashrc这个文件里面加上一句话: export LANG=‘en_US’ 如果想使用其他界面,把en_US改成其他语言对应的地区代码就行了,比如说zh_CN。其实LANG的"完全体"是"地区.编码"这样的结构。所以如果要想自己设置编码,还需要在zh_CN的后面加上编码——这里用GBK来说明——使其变成zh_CN.GBK。在这里我们要让界面是英文同时能让中文也能显示,所以将LANG设置成en_US.GBK。 到此界面语言修改完成,简单吧?事情没那么简单,在cygwin下面,只做这样的设置,会让vi等软件出现匪夷所思的现象,难道是……打开方式不 对?No,其实语言的设置还没完。执行locale命令,会返回给你目前所有语言设置,可以说有关语言设置的项目还是挺丰富的嘛,LC下还有许多要设置 的,不过LC下面有一个LC_ALL,看样子设置他就行了,.bashrc加上一句: export LC_ALL=‘en_US.GBK’ Bingo!重启cygwin之后,vi恢复正常行为。 转载自 http://hi.baidu.com/chrisyue/blog/item/41225fe79cedb33db838207a .html

2016-01-14 · 1 min · 20 words · -

MySQL Fabric

MySQL Fabric http://www.2cto.com/database/201408/327941.html Oracle在今年5月推出了一套为各方寄予厚望的MySQL产品 - MySQL Fabric,从字面上不太能看出它是啥,但是从名称上还是有迹可循的。fabric是"织物"的意思,这意味着它是用来"织"起一片MySQL数据库。MySQL Fabric是一套数据库服务器场(Database Server Farm)的架构管理系统。 MySQL Fabric是什么? MySQL Fabric能"组织"多个MySQL数据库,是应用系统将大于几TB的表分散到多个数据库,即数据分片(Data Shard)。在同一个分片内又可以含有多个数据库,并且由Fabric自动挑选一个适合的作为主数据库,其他的数据库配置成从数据库,来做主从复制。在主数据库挂掉时,从各个从数据库中挑选一个提升为主数据库。之后,其他的从数据库转向新的主数据库复制新的数据。注意: 这里说的"自动"是指由MySQL Fabric在后台完成,而不需要用户手动更改配置。最重要的是,MySQL Fabric是GPL的开源软件,也就是在符合GPL的规范下,你可以自由的使用和修改这个软件。MySQL Fabric要解决的问题 为什么做数据分片?当你的应用需要处理的表大于1TB的数据时,Data Shard常常是必须的。这么大的表,无论在查询、更新的效率上,或者是备份、更改结构所需要的时间上,都会造成很大的问题。然而当你将这么大的表分散到多个数据库服务器上,又会使每一台数据库服务器都有可能是单个故障点。只要有一台挂掉就会使整个系统的操作发生问题。另一方面,应用端的程序也会因为每个查询都要依其查询条件(where子句的内容)分别指向不同的数据库而变得更加复杂。再者,当数据分片的结构改变时(例如增加一个数据库),会使应用端的所有程序都必须修改,从而导致维护变得极为复杂。为了解决应用程序复杂度增加的问题,有人在应用程序和数据库服务器之间增加一个代理(proxy)或者成为switch,应用程序所有对数据库的指令先送到proxy,再由proxy判断要转到哪个数据库。下图就是这个方案的示意图。这也许可以解决应用程序难以维护的问题,但是当应用端的数量增加,数据库分片增加,或者系统压力增加时,这个switch会成为容量及性能的瓶颈和单点故障(当它宕掉时,应用端找不到数据库),而且所有的数据库指令均需要传两次(先到switch再到数据库)。每个查询都会造成额外的负荷。 MySQL Fabric的架构 MySQL Fabric采用不用的做法,其架构如下图所示。主要的特点是把switch合并到各应用端的connector中,以解决单一switch的单点故障和性能瓶颈。 MySQL Fabric由三个部分构成: 1.MySQL Fabric管理节点: 是一个python脚本,是整个架构的核心。MySQL Fabric管理节点主要的功能是管理整个数据库服务器场(Database Server Farm),它启动时会找/etc/MySQL/fabric.cnf这个配置文件,由它指定fabric背后当成存放Server Farm架构和配置之repository的MySQL数据库位置、端口和连接账号等信息。Fabric在初始化时(执行MySQLfabric manage setup命令),会在MySQL数据库上开一个schema(通常是名称为fabric的database),存放Server Farm的配置相关信息,如哪些服务器组由哪些数据库构成,各服务器组中的主从服务器分别是哪些,等等。MySQL Fabric节点在设置配置时,会对Server Farm中各数据库下达建立主从复制的命令(上图的红色线条)。在正常运行时定期ping各组的主服务器 ,当发现主数据库没有正常运行时,它会启动故障转移程序,在该server farm的从数据库中找一个合适的提升为主服务器。其他的从数据库则转向新的主数据库继续复制数据。 数据库服务器场(database server farm) 这是整个架构中的工作引擎,在传统的数据库应用中这是单一的MySQL数据库,MySQL Fabric则是以多个数据库支持大数据量表(TB级以上)和高可用性数据库的需求。这些数据库分成几个高可用组(HA Group),每个组包含一个以上的数据库服务器,上图中最下面的几个灰色和浅蓝色的方块代表高可用组。如果高可用组中有多个数据库,MySQL Fabric会挑选(使用命令MySQLfabric group promote命令)一个提升为主数据库(Master),其他数据库则成为从数据库(Slave),从数据库复制主数据库的变化,完成设定同一高可用组内的主从复制。以后,Fabric会定期件事这个主数据库。当主数据宕掉之后,Fabric会从高可用组内挑选一个提升为主数据库,其他的数据库会转向这个新的主数据库继续复制。另一方面,MySQL Fabric也会只是应用端的conector对这些主从数据库做读写分离,当应用程序对数据库做读写兼有的操作时,connector会将该指令提交给主数据库。如果应用程序只会对数据库进行读操作,且连线的read_only参数设置为"ON",则所有的查询均轮流传送到这几个数据库。借助读写分离,应用系统的资料处理能力得以增加。此外,如前面所述,MySQL Fabric还能处理需要拆分到多个数据库服务器的表(sharding tables),每一个高可用组都可能存放shard table的部分数据。应用端的connector会将对shard table的指令依MySQL Fabric的管理节点的设定送到不同的高可用组,这样可使数据库的容量随着高可用组的数量增加而增长。同时,对非拆分的表所下的指令和所有的DDL会由connector送到全局高可用组(global group),全局高可用组的主数据库被MySQL Fabric设置为其他高可用组的主数据库。所有存拆分表的高可用组的主数据库复制global group的变化,这么一来其他高可用组都有一份非拆分表的资料。从而使得SQL中拆分表对非拆分表的JOIN操作变得更简单。3. Connector 应用系统在运行时,每个SQL指令都会经由connector发送到数据库。MySQL Fabric所搭配的connector和一般使用单机的MySQL数据库一样,只是在较新版的connector是fabric aware connector多了一些能处理数据库服务器场(database server farm)的功能。使他们能在建立数据库连接时,以XML-RPC协议检查MySQL Fabric的管理节点中server farm的配置,然后通过该连接下的查询可依fabric的指示送到适合的数据库。如此一来,常见的database shard方案中可能造成性能瓶颈的proxy放到connector中,从而解决了这个问题。目前MySQL Fabric支持的技术有java、python、PHP,即Connector/J、Connector/Python和Connector/PHP都是Fabric-aware。以java为例,JDBC driver必须是Connector/J 5.1.30以后的版本,Fabric的Java程序和一般对单机MySQL的查询的Java程序差不多,只是在建立database connection object时database connection URL不是指向数据库,改为指向MySQL Fabric管理节点(服务器的IP和端口通常是32274)。当查询的表时全局表(不做table shard)或DDL(例如建表或改表结构)时,建立connection object的要加上"fabricServerGroup=“参数,之后通过这个connection object所下的SQL指令会送到Global Group的主数据库,再由数据库复制到其他的高可用组(shard)中。如果SQL命令所要操作的表时分区表(shard table),则建立connection object时要在参数加上"fabricShardTable=“参数,之后通过这个connection object所下的SQL命令会根据MySQL Fabric所设定的分表(shard)原则送到各分区(shard)的高可用组。这样一来,应用程序对这些shard table下的SQL指令时,不需要在SQL中判断要送到哪个数据库,完全由connector在建立数据库连接时向MySQL Fabric所查到的server farm的配置信息(哪个数据库属于哪个shard group,各shard table的拆分原则等)所决定。而且这个配置在建立主连接后就缓存在Connector所在的应用端。这样,在每次下SQL指令时就不需要重复查询MySQL Fabric管理节点,而依存于应用端的分表配置直接送到正确的数据库。而应用程序的效率不会因为做了表的拆分而有任何降低。结语 ...

2016-01-12 · 1 min · 96 words · -

MySQL默认排序

MySQL默认排序 SELECT * FROM tbl – this will do a “table scan”. If the table has never had any DELETEs/REPLACEs/UPDATEs, the records will happen to be in the insertion order, hence what you observed. 大致意思为,一个myisam引擎表在没有任何的删除,修改操作下,执行 select 不带order by,那么会按照插入顺序进行排序。 If you had done the same statement with an InnoDB table, they would have been delivered in PRIMARY KEY order, not INSERT order. Again, this is an artifact of the underlying implementation, not something to depend on. 对于innodb引擎表来说,在相同的情况下,select 不带order by,会根据主键来排序,从小到大

2016-01-12 · 1 min · 78 words · -

Netty 中 IOException,Connection reset by peer 与 java.nio.channels.ClosedChannelException,null

‘Netty 中 IOException,Connection reset by peer 与 java.nio.channels.ClosedChannelException,null’ http://www.cnblogs.com/zemliu/p/3864131.html 最近发现系统中出现了很多 IOException: Connection reset by peer 与 ClosedChannelException: null 深入看了看代码, 做了些测试, 发现 Connection reset 会在客户端不知道 channel 被关闭的情况下, 触发了 eventloop 的 unsafe.read() 操作抛出 而 ClosedChannelException 一般是由 Netty 主动抛出的, 在 AbstractChannel 以及 SSLHandler 里都可以看到 ClosedChannel 相关的代码 AbstractChannel static final ClosedChannelException CLOSED_CHANNEL_EXCEPTION = new ClosedChannelException(); static { CLOSED_CHANNEL_EXCEPTION.setStackTrace(EmptyArrays.EMPTY_STACK_TRACE); NOT_YET_CONNECTED_EXCEPTION.setStackTrace(EmptyArrays.EMPTY_STACK_TRACE); } @Override public void write(Object msg, ChannelPromise promise) { ChannelOutboundBuffer outboundBuffer = this.outboundBuffer; if (outboundBuffer == null) { // If the outboundBuffer is null we know the channel was closed and so // need to fail the future right away. If it is not null the handling of the rest // will be done in flush0() // See https://github.com/netty/netty/issues/2362 safeSetFailure(promise, CLOSED_CHANNEL_EXCEPTION); // release message now to prevent resource-leak ReferenceCountUtil.release(msg); return; } outboundBuffer.addMessage(msg, promise); } ...

2016-01-07 · 5 min · 878 words · -

RTEMS

RTEMS 为什么需要操作系统? 1.计算机是由CPU、内存、磁盘、显卡、声卡等许许多多设备组成的,而且这些设备的厂商众多,品种繁多,而且不同厂商生产的同种设备虽然完成同种功能,但是具体细节却存在千差万别; 2.为了正确地管理和使用这些设备来实现具体的应用,这样程序员就得了解和掌握各种设备的工作原理。而且对于同种设备,由于不同的硬件厂商在实现细节上的差异使得程序员再次陷入了复杂的硬件控制的深渊。 3.在硬件的基础上加载一层软件来管理整个系统; 4.操作系统通过设备驱动程序来与计算机硬件打交道,通过一系列的功能模块将整个计算机硬件系统抽象成为一个公共、统一、开放的接口,从而使得程序员不必再陷入各种硬件系统的具体细节。 什么是操作系统? 1.操作系统(Operating System,简称OS)是管理计算机系统的全部硬件资源包括软件资源及数据资源; 2.控制程序运行; 3.改善人机界面; 4.为其它应用软件提供支持等,使计算机系统所有资源最大限度地发挥作用; 5.为用户提供方便的、有效的、友善的服务界面。 什么是实时操作系统(RTOS)? 实时操作系统(RTOS)是指当外界事件或数据产生时,能够接受并以足够快的速度予以处理,其处理的结果又能在规定的时间之内来控制生产过程或对处理系统作出快速响应,并控制所有实时任务协调一致运行的操作系统。 什么是实时? 响应时间快: 事件发生后,能以最快的速度对事件进行响应; 响应时间是确定的: 事件处理的延迟时间、处理持续时间、处理截止时间都有上限与下限,所有动作必须在这个时间范围内发生。 RTOS分类? 实时操作系统有硬实时和软实时之分: 硬实时要求在规定的时间内必须完成操作,否则会引起非常严重的错误,这是在操作系统设计时保证的; 软实时则只要按照任务的优先级,尽可能快地完成操作即可。 什么是TRON? TRON 全称是 (The Real-time Operating system Nucleus); ITRON(Industrial TRON)是一个由多家著名IT企业牵头的协议制定组织,同时IRTON也代表实时嵌入式系统的一个标准; ITRON提出了实时操作系统的一系列规范(包括系统调用接口规范,任务调度接口规范,TCP/IP网路链接API规范,本地与远程调试接口规范等等),遵循这个规范的操作系统上层软件可以相互移植。

2016-01-06 · 1 min · 35 words · -

maven profile

maven profile http://haohaoxuexi.iteye.com/blog/1900568 4 profile介绍 4.1 profile简介 profile可以让我们定义一系列的配置信息,然后指定其激活条件。这样我们就可以定义多个profile,然后每个profile对应不同的激活条件和配置信息,从而达到不同环境使用不同配置信息的效果。比如说,我们可以通过profile定义在jdk1.5以上使用一套配置信息,在jdk1.5以下使用另外一套配置信息;或者有时候我们可以通过操作系统的不同来使用不同的配置信息,比如windows下是一套信息,linux下又是另外一套信息,等等。具体的激活条件有哪些我在后文会讲到。 4.2 profile的定义位置 对于使用Maven3,我们可以有多个地方定义profile。定义的地方不同,它的作用范围也不同。 (1) 针对于特定项目的profile配置我们可以定义在该项目的pom.xml中。 (2) 针对于特定用户的profile配置,我们可以在用户的settings.xml文件中定义profile。该文件在用户家目录下的".m2"目录下。 (3) 全局的profile配置。全局的profile是定义在Maven安装目录下的"conf/settings.xml"文件中的。 4.3 profile中能定义的信息 profile中能够定义的配置信息跟profile所处的位置是相关的。以下就分两种情况来讨论,一种是定义在settings.xml中,另一种是定义在pom.xml中。 4.3.1 profile定义在settings.xml中 当profile定义在settings.xml中时意味着该profile是全局的,它会对所有项目或者某一用户的所有项目都产生作用。因为它是全局的,所以在settings.xml中只能定义一些相对而言范围宽泛一点的配置信息,比如远程仓库等。而一些比较细致一点的需要根据项目的不同来定义的就需要定义在项目的pom.xml中。具体而言,能够定义在settings.xml中的信息有 、和。定义在里面的键值对可以在pom.xml中使用。 4.3.2 profile定义在pom.xml中 定义在pom.xml中的profile可以定义更多的信息。主要有以下这些: l l l l l ...

2016-01-06 · 1 min · 145 words · -

nftables iptables

nftables iptables 跟iptables相比,nftables带来了一系列的好处 更易用易理解的语法 表和链是完全可配置的 匹配和目标之间不再有区别 在一个规则中可以定义多个动作 每个链和规则都没有内建的计数器 更好的动态规则集更新支持 简化IPv4/IPv6双栈管理 支持set/map等 支持级连 (需要内核4.1+) 新的防火墙子系统/包过滤引擎Nftables将在Linux3.13中替代有十多年历史的iptables。iptables/netfilter在2001年加入到2.4内核中。诞生于2008年的NFTables设计替代iptables,它提供了一个更简单的kernelABI,减少重复代码,改进错误报告,更有效的支持过滤规则。 除了iptables,NFTables还将替代ip6tables、arptables和ebtables。Linux内核的第一代包过滤机制是ipfwadm (1.2.1内核,1995年) ,之后是ipchains (1999年) ,iptables、Nftables是第四代。 http://luxiaok.blog.51cto.com/2177896/1312846 http://segmentfault.com/a/1190000000410970 Linux 3.13 带来了很多特性。nftables也是第一次正式发布。nftables是一个致力于替换现有的{ip,ip6,arp,eb}tables框架 (也就是大家熟知的iptables) 的项目。然而,Linux3.13中的nftables版本还是不完整的,还缺少一些重要的特性。这些特性会在后续的Linux版本中发布。大多数场景下nftables已经可以使用,但是完整的支持 (即,nftables优先级高于iptables) 应该在Linux 3.15。 nftables引入了一个新的命令行工具nft。nft是iptables及其衍生指令 (ip6tables,arptables) 的超集。同时,nft拥有完全不同的语法。是的,如果你习惯于iptables,这是个不好的消息。但是有一个兼容层允许你使用iptables,而过滤是由内核中的nftables完成的。 到目前为止,只有非常少的文档资料。你可以找到我的nftables快速开始,其他的一些初步文档很快就会公开。

2016-01-05 · 1 min · 33 words · -

SSDP

SSDP 简单服务发现协议 (SSDP,Simple Service Discovery Protocol) 是一种应用层协议,是构成通用即插即用(UPnP)技术的核心协议之一。简单服务发现协议提供了在局部网络里面发现设备的机制。控制点 (也就是接受服务的客户端) 可以通过使用简单服务发现协议,根据自己的需要查询在自己所在的局部网络里面提供特定服务的设备。设备 (也就是提供服务的服务器端) 也可以通过使用简单服务发现协议,向自己所在的局部网络里面的控制点声明它的存在。[1] 简单服务发现协议是在HTTPU和HTTPMU的基础上实现的协议。[1] 按照协议的规定,当一个控制点 (客户端) 接入网络的时候,它可以向一个特定的多播地址的SSDP端口使用M-SEARCH方法发送"ssdp:discover"消息。当设备监听到这个保留的多播地址上由控制点发送的消息的时候,设备会分析控制点请求的服务,如果自身提供了控制点请求的服务,设备将通过单播的方式直接响应控制点的请求。[2] 类似的,当一个设备接入网络的时候,它应当向一个特定的多播地址的SSDP端口使用NOTIFY方法发送"ssdp:alive"消息。控制点根据自己的策略,处理监听到的消息。考虑到设备可能在没有通知的情况下停止服务或者从网络上卸载,“ssdp:alive"消息必须在HTTP协议头CACHE-CONTROL里面指定超时值,设备必须在约定的超时值到达以前重发"ssdp:alive"消息。如果控制点在指定的超时值内没有再次收到设备发送的"ssdp:alive"消息,控制点将认为设备已经失效。[2] 当一个设备计划从网络上卸载的时候,它也应当向一个特定的多播地址的SSDP端口使用NOTIFY方法发送"ssdp:byebye"消息。但是,即使没有发送"ssdp:byebye"消息,控制点也会根据"ssdp:alive"消息指定的超时值,将超时并且没有再次收到的"ssdp:alive"消息对应的设备认为是失效的设备。[2] 在IPv4环境,当需要使用多播方式传送相关消息的时候,SSDP一般使用多播地址239.255.255.250和UDP端口号1900。 根据互联网地址指派机构的指派,SSDP在IPv6环境下使用多播地址FF0x::C,这里的X根据scope的不同可以有不同的取值。[3]

2016-01-05 · 1 min · 19 words · -

appassembler-maven-plugin

appassembler-maven-plugin Goals Overview appassembler:assemble Assembles the artifacts and generates bin scripts for the configured applications. appassembler:create-repository Creates an appassembler repository. appassembler:generate-daemons Generates JSW based daemon wrappers. maven 自动生成运行脚本插件appassembler-maven-plugin 博客分类: maven appassembler-maven-plugin可以自动生成跨平台的启动脚本,省去了手工写脚本的麻烦,而且还可以生成jsw的后台运行程序。 appassembler的配置比较简单,在pom.xml的配置文件加入插件配置。 比如说不同的启动脚本,可以如下配置 Xml代码 org.codehaus.mojo appassembler-maven-plugin 1.2.1 conf ...

2016-01-05 · 1 min · 110 words · -

Java Service Wrapper

Java Service Wrapper http://www.cnblogs.com/fsjohnhuang/p/4019267.html Java魔法堂: 以Windows服务的形式运行Java程序 一、前言 由于防止维护人员误操作关闭Java控制台程序,因此决定将其改造为以Windows服务的形式运行。弄了一个上午总算搞定了,下面记录下来,以供日后查阅。 二、Java Service Wrapper 官网地址: http://wrapper.tanukisoftware.com/doc/english/download.jsp JavaServiceWrapper以守护进程或windows服务的方式运行java程序。JSW提供四种方案改造原有项目,以实现守护进程或windows服务的方式运行。而且还提供JVM监控功能和自动重启功能,反正十分强大的样子。 方式1: WrapperSimpleApp 用于通过同一个类实现启动和关闭的程序。 官方推荐使用该方式加工原有项目,好处是简单,且不用修改原有项目的代码。 步骤1: 下载并解压得到工具包,目录结构如下 / |- bin,wrapper控制windows服务的bat文件 |- conf,wrapper配置文件 |- doc,教程 |- lib,wrapper的依赖包 |- logs,日志 |- src,模板 |- conf |- bin 步骤2: 搭建项目结构: 新建项目发布目录 (假设为agent) ,然后将src下的conf和bin复制到agent下,并且将conf和bin下的文件重命名,去掉`.in`后缀。然后将bin/wrapper.exe复制到agent/bin/下,再将lib复制到agent下,得到目录结构如下 agent |- lib |- wrapper.dll |- wrapper.jar |- conf |- wrapper.conf |- bin |- wrapper.exe |- 一堆bat文件 最后将原有项目的文件复制到bin目录下。 步骤3: 配置agent/conf/wrapper.conf的参数 配置java命令路径 wrapper.java.command=jre/bin/java 配置CLASSPATH路径 (并不会修改全局的环境变量) 若原有项目还依赖其他jar包,均需要添加进来 wrapper.java.classpath.1=../lib/wrapper.jar wrapper.java.classpath.2=. 配置lib路径 wrapper.java.library.path.1=../lib 配置服务的main class (就是原有项目的程序入口类) wrapper.app.parameter.1=agent.Daemon ...

2016-01-05 · 1 min · 119 words · -

java 9

java 9 Java 9 正式发布于 2017 年 9 月 21 日 Java 9 带 来了很多重大的变化。其中最重要的改动是 Java 平台模块系统的引入。 jlink 工具 Java 9中有代表性的项目: Kulla项目 (创建Java REPL) Valhalla项目 (改进Java类型) Jigswa项目 (增加模块化功能) http://www.infoq.com/cn/news/2015/05/Java-9-On-Track-For-2016 https://www.ibm.com/developerworks/cn/java/the-new-features-of-Java-9/index.html

2016-01-05 · 1 min · 30 words · -

BCM Body Control Module

BCM Body Control Module http://club.autohome.com.cn/bbs/thread-c-2137-14886528-1.html 车身控制器BCM(Body Control Module) 与其相关的还有ABM (Air Bag Module) 与熟识的ABS模块系统,BCM主要涉及车体中灯,门,窗及车身防盗部分,与其他模块共同承担整车的性能与安全的实现,为驾驶带来更多的智能与舒适。 BCM控制技术的方式 BCM控制技术有三种方式: 分散式、集中式和分布式(总线式)。 目前国内采用分散式 bcm的车型主要是经济型轿车,如、旗云、自由舰、伊兰特、爱丽舍、捷达等;用集中式bcm的车型较少,代表车型有御翔、天籁、颐达、骐达、尊驰、骏捷等;中高档轿车多采用分布式bcm,如帕萨特、途安、雅阁、凯旋、奥迪、速腾、蒙迪欧、皇冠、君威、派朗等。 发展趋势 BCM具有以下发展趋势: 越来越多的车身电子设备在车身得到应用,使得BCM控制对象更多;各电子设备的功能越来越多,各种功能都需要通过BCM来实现,使得BCM功能更加强大;各电子设备之间的信息共享越来越多,一个信息可同时供许多部件使用,要求BCM的数据通信功能越来越强;单一集中式BCM很难完成越来越庞大的功能,使得总线式、网络化BCM成为发展趋势。 CAN总线是一种串行多主站总线,是一种有效支持分布式控制或实时控制的串行通信网络。由于其通信速率高,可靠性好以及价格低廉等特点,使其特别适合汽车系统,所以利用CAN总线技术总线式控制车身电子电器装置是BCM发展的必然趋势。 Lin总线也常常应用于BCM通信中,在通信量不大,速率要求不高的低端控制,如自动雨刮及车门防夹功能的实现都是由lin线完成的,这样即满足了要求,又降低了成本。

2016-01-04 · 1 min · 23 words · -

java exit code

java exit code http://blog.sina.com.cn/s/blog_5396eb53010004sg.html The number is only the status code for the termination of the JVM. It does not effect the actual command. By convention 0 means a normal exit, anything else signifies an abnormal termination. You can actually return any int not just a 1 or 0. A common searching for was found, Exit 1 means that the text you were searching for was not found and Exit 2 means it barfed. To get a handle no the exit status, the env variable "$?" is the return status of the last command. So try this: bash$ cat "SOME_FILE_THAT_DOES_NOT_EXIST" bash$ echo $? and your result should be 1. ...

2015-12-30 · 1 min · 125 words · -

java shutdown hook

java shutdown hook 在线上Java程序中经常遇到进程程挂掉,一些状态没有正确的保存下来,这时候就需要在JVM关掉的时候执行一些清理现场的代码。Java中得ShutdownHook提供了比较好的方案。 JDK在1.3之后提供了Java Runtime.addShutdownHook(Thread hook)方法,可以注册一个JVM关闭的钩子,这个钩子可以在以下几种场景被调用: 程序正常退出 使用System.exit() 终端使用Ctrl+C触发的中断 系统关闭 使用Kill pid命令干掉进程 注: 在使用kill -9 pid是不会JVM注册的钩子不会被调用。 http://blog.csdn.net/hemingwang0902/article/details/6207682 http://www.cnblogs.com/nexiyi/p/java_add_ShutdownHook.html

2015-12-30 · 1 min · 19 words · -

apache ab/Apache Bench

apache ab/Apache Bench ApacheBench install yay -S apache-tools sudo yum -y install httpd-tools 格式: ab [options] [http://]hostname[:port]/path # get 请求, 不带 -p参数时 发get请求 ab -n 1 -c 1 -T 'application/x-www-form-urlencoded' "http://127.0.0.1:7000/" #post 请求 ab -n 1 -c 1 -p abpost.txt -T 'application/x-www-form-urlencoded' "http://127.0.0.1:7000/" ab -n 1 -c 1 -p abpost.txt -T 'application/json' "http://127.0.0.1:8080/" 参数: -n requests Number of requests to perform //在测试会话中所执行的请求个数 (本次测试总共要访问页面的次数) 。默认时,仅执行一个请求。 -c concurrency Number of multiple requests to make //一次产生的请求个数 (并发数) 。默认是一次一个。 -t timelimit Seconds to max. wait for responses ...

2015-12-25 · 2 min · 350 words · -

ConcurrentHashMap Collections.synchronizedMap

ConcurrentHashMap Collections.synchronizedMap ConcurrentHashMap, Collections.synchronizedMap和Hashtable讨论 在Java类库中出现的第一个关联的集合类是Hashtable,它是JDK1.0的一部分。 Hashtable提供了一种易于使用的、线程安全的、关联的map功能,这当然也是方便的。然而,线程安全性是凭代价换来的――Hashtable的所有方法都是同步的。此时,无竞争的同步会导致可观的性能代价。Hashtable的后继者HashMap是作为JDK1.2中的集合框架的一部分出现的,它通过提供一个不同步的基类和一个同步的包装器Collections.synchronizedMap,解决了线程安全性问题。 通过将基本的功能从线程安全性中分离开来,Collections.synchronizedMap允许需要同步的用户可以拥有同步,而不需要同步的用户则不必为同步付出代价。Hashtable和synchronizedMap所采取的获得同步的简单方法 (同步Hashtable中或者同步的Map包装器对象中的每个方法) 有两个主要的不足。首先,这种方法对于可伸缩性是一种障碍,因为一次只能有一个线程可以访问hash表。同时,这样仍不足以提供真正的线程安全性,许多公用的混合操作仍然需要额外的同步。 虽然诸如get()和put()之类的简单操作可以在不需要额外同步的情况下安全地完成,但还是有一些公用的操作序列,例如迭代或者put-if-absent (空则放入) ,需要外部的同步,以避免数据争用。有条件的线程安全性同步的集合包装器 synchronizedMap和synchronizedList,有时也被称作有条件地线程安全――所有单个的操作都是线程安全的,但是多个操作组成的操作序列却可能导致数据争用,因为在操作序列中控制流取决于前面操作的结果。 如果一个条目不在Map中,那么添加这个条目。不幸的是,在 containsKey()方法返回到put()方法被调用这段时间内,可能会有另一个线程也插入一个带有相同键的值。如果您想确保只有一次插入,您需要用一个对Map进行同步的同步块将这一对语句包装起来。List.size()的结果在循环的执行期间可能会变得无效,因为另一个线程可以从这个列表中删除条目。可能在进入循环的最后一次迭代之后有一个条目被另一个线程删除了,则List.get()将返回null,抛出一个 NullPointerException异常。那么,采取什么措施才能避免这种情况呢?如果当您正在迭代一个List时另一个线程也可能正在访问这个 List,那么在进行迭代时您必须使用一个synchronized块将这个List包装起来,在List上同步,从而锁住整个List。 这样做虽然解决了数据争用问题,但是在并发性方面付出了更多的代价,因为在迭代期间锁住整个List会阻塞其他线程,使它们在很长一段时间内不能访问这个列表。集合框架引入了迭代器,用于遍历一个列表或者其他集合,从而优化了对一个集合中的元素进行迭代的过程。然而,在java.util集合类中实现的迭代器极易崩溃,也就是说,如果在一个线程正在通过一个Iterator遍历集合时,另一个线程也来修改这个集合,那么接下来的 Iterator.hasNext()或Iterator.next()调用,会抛出ConcurrentModificationException异常。 如果想要防止出现ConcurrentModificationException异常,那么当您正在进行迭代时,您必须使用一个在 Listl上同步的synchronized块将该List包装起来,从而锁住整个List。 (也可以调用List.toArray(),在不同步的情况下对数组进行迭代,但是如果列表比较大的话这样做代价很高) 。 而ConcurrentHashMap是DougLea的util.concurrent包的一部分,现已被集成到 JDK5.0中,它提供比Hashtable或者synchronizedMap更高程度的并发性。而且,对于大多数成功的get()操作它会设法避免完全锁定,其结果就是使得并发应用程序有着非常好的吞吐量。 1 针对吞吐量进行优化 ConcurrentHashMap使用了几个技巧来获得高程度的并发以及避免锁定,包括为不同的hashbucket (桶) 使用多个写锁和使用 JMM 的不确定性来最小化锁被保持的时间——或者根本避免获取锁。对于大多数一般用法来说它是经过优化的,这些用法往往会检索一个很可能在map中已经存在的值。事实上,多数成功的get()操作根本不需要任何锁定就能运行。 (警告: 不要自己试图这样做!想比 JMM 聪明不像看上去的那么容易。util.concurrent类是由并发专家编写的,并且在 JMM 安全性方面经过了严格的同行评审。) 2 多个写锁 我们可以回想一下,Hashtable (或者替代方案 Collections.synchronizedMap) 的可伸缩性的主要障碍是它使用了一个map范围 (map-wide) 的锁,为了保证插入、删除或者检索操作的完整性必须保持这样一个锁,而且有时候甚至还要为了保证迭代遍历操作的完整性保持这样一个锁。这样一来,只要锁被保持,就从根本上阻止了其他线程访问Map,即使处理器有空闲也不能访问,这样大大地限制了并发性。 ConcurrentHashMap摒弃了单一的map范围的锁,取而代之的是由32个锁组成的集合,其中每个锁负责保护hashbucket的一个子集。锁主要由变化性操作 (put()和remove()) 使用。具有32 个独立的锁意味着最多可以有32个线程可以同时修改map。这并不一定是说在并发地对map进行写操作的线程数少于32时,另外的写操作不会被阻塞—— 32对于写线程来说是理论上的并发限制数目,但是实际上可能达不到这个值。但是,32依然比1要好得多,而且对于运行于目前这一代的计算机系统上的大多数应用程序来说已经足够了。 3 map范围的操作 有32个独立的锁,其中每个锁保护hashbucket的一个子集,这样需要独占访问 map的操作就必须获得所有32个锁。一些map范围的操作,比如说size()和isEmpty(),也许能够不用一次锁整个map (通过适当地限定这些操作的语义) ,但是有些操作,比如map重排 (扩大hashbucket的数量,随着map的增长重新分布元素) ,则必须保证独占访问。Java语言不提供用于获取可变大小的锁集合的简便方法。必须这么做的情况很少见,一旦碰到这种情况,可以用递归方法来实现。 JMM概述 在进入 put()、get()和remove()的实现之前,让我们先简单地看一下 JMM。JMM 掌管着一个线程对内存的动作 (读和写) 影响其他线程对内存的动作的方式。由于使用处理器寄存器和预处理cache来提高内存访问速度带来的性能提升,Java语言规范 (JLS) 允许一些内存操作并不对于所有其他线程立即可见。有两种语言机制可用于保证跨线程内存操作的一致性——synchronized和volatile。 按照JLS的说法,“在没有显式同步的情况下,一个实现可以自由地更新主存,更新时所采取的顺序可能是出人意料的。“其意思是说,如果没有同步的话,在一个给定线程中某种顺序的写操作对于另外一个不同的线程来说可能呈现出不同的顺序,并且对内存变量的更新从一个线程传播到另外一个线程的时间是不可预测的。 虽然使用同步最常见的原因是保证对代码关键部分的原子访问,但实际上同步提供三个独立的功能——原子性、可见性和顺序性。原子性非常简单——同步实施一个可重入的 (reentrant) 互斥,防止多于一个的线程同时执行由一个给定的监视器保护的代码块。不幸的是,多数文章都只关注原子性方面,而忽略了其他方面。但是同步在JMM中也扮演着很重要的角色,会引起JVM在获得和释放监视器的时候执行内存壁垒 (memorybarrier) 。 ...

2015-12-24 · 1 min · 83 words · -

Fluent Interface, fluent manner, fluent 风格, 流式接口, 流式风格

Fluent Interface, fluent manner, fluent 风格, 流式接口, 流式风格 这个故事是从下面这样一个对外暴露接口的调用开始的。 queryUserEvent event = new QueryUserEvent(); event.setName(name); event.setAge(18); event.setType(QueryUserEvent.TYPE_NORMAL); event.setSex(QueryUserEvent.SEX_MALE); //... List<User> userList = userService.query(event); 我想做的事情其实很简单,我想查询一个用户列表,可是接口参数的拼装让我感到头疼,这样的代码太过啰嗦,我希望有可读性更好的解决办法。 P兄台说,如果我直接传入一个user对象,是不是可以避开了这个未必带来多少好处的event? User user = new User(); user.setName(name); user.setAge(18); user.setSex(QueryUserEvent.SEX_MALE); // …… List<User> userList = userService.query(user, UserService.QUERY_TYPE_NORMAL); 我有时候会考虑你说的办法的,可是,你没有解决实际的问题,我现在的最大问题在于,这一堆的setXXX方法,它破坏了我构造这个查询条件对象的流畅性。 他紧接着说,那要不然,我们把setXXX方法的劳动省下来,让构造器来替我们完成这个任务吧: User user = new User(name, 18, QueryUserEvent.SEX_MALE, ……); List<User> userList = userService.query(user, UserService.QUERY_TYPE_NORMAL); 我说,你的办法看起来不错,不过有时候按你的办法做,我的构造方法会变得臃肿无比,比如出现十多个参数; 另外还有一个问题,假如说,我的查询条件是简单的 (我只需要根据年龄查询) ,那么其它的参数都要写成null,类似这样子: User user = new User(null, 18, null, null, null, null, ……); List<User> userList = userService.query(user, UserService.QUERY_TYPE_NORMAL); 天,让谁去阅读这样的代码,他都不会喜欢的。 ...

2015-12-23 · 1 min · 205 words · -

Curator

Curator http://macrochen.iteye.com/blog/1366136 Curator 是 Netflix 开源的一套 ZooKeeper 客户端框架. Netflix 在使用ZooKeeper的过程中发现ZooKeeper自带的客户端太底层, 应用方在使用的时候需要自己处理很多事情, 于是在它的基础上包装了一下, 提供了一套更好用的客户端框架. Netflix在用ZooKeeper的过程中遇到的问题, 我们也遇到了, 所以开始研究一下, 首先从他在github上的源码, wiki文档以及Netflix的技术blog入手. 看完官方的文档之后, 发现Curator主要解决了三类问题: 封装ZooKeeper client与ZooKeeper server之间的连接处理; 提供了一套Fluent风格的操作API; 提供ZooKeeper各种应用场景(recipe, 比如共享锁服务, 集群领导选举机制)的抽象封装. Curator列举的ZooKeeper使用过程中的几个问题 初始化连接的问题: 在client与server之间握手建立连接的过程中, 如果握手失败, 执行所有的同步方法(比如create, getData等)将抛出异常 自动恢复(failover)的问题: 当client与一台server的连接丢失,并试图去连接另外一台server时, client将回到初始连接模式 session过期的问题: 在极端情况下, 出现ZooKeeper session过期, 客户端需要自己去监听该状态并重新创建ZooKeeper实例 . 对可恢复异常的处理:当在server端创建一个有序ZNode, 而在将节点名返回给客户端时崩溃, 此时client端抛出可恢复的异常, 用户需要自己捕获这些异常并进行重试 使用场景的问题:Zookeeper提供了一些标准的使用场景支持, 但是ZooKeeper对这些功能的使用说明文档很少, 而且很容易用错. 在一些极端场景下如何处理, zk并没有给出详细的文档说明. 比如共享锁服务, 当服务器端创建临时顺序节点成功, 但是在客户端接收到节点名之前挂掉了, 如果不能很好的处理这种情况, 将导致死锁. Curator主要从以下几个方面降低了zk使用的复杂性: 重试机制:提供可插拔的重试机制, 它将给捕获所有可恢复的异常配置一个重试策略, 并且内部也提供了几种标准的重试策略(比如指数补偿). 连接状态监控: Curator初始化之后会一直的对zk连接进行监听, 一旦发现连接状态发生变化, 将作出相应的处理. zk客户端实例管理:Curator对zk客户端到server集群连接进行管理. 并在需要的情况, 重建zk实例, 保证与zk集群的可靠连接 各种使用场景支持:Curator实现zk支持的大部分使用场景支持(甚至包括zk自身不支持的场景), 这些实现都遵循了zk的最佳实践, 并考虑了各种极端情况. ...

2015-12-23 · 3 min · 613 words · -