WNDR4300 openwrt

‘WNDR4300 openwrt’ https://wiki.openwrt.org/zh-cn/toh/netgear/wndr4300 WNDR4300 Flash容量: 128 MiB NAND RAM: 128 MiB mips, not mipsle go build … GOMIPS=softfloat WNDR4300有两种固件,一种为 …ubi-factory.img 格式,一种为 …squashfs-sysupgrade.tar 格式。 其中 img 格式只能用 tftp 的方法刷入。而 tar 只能通过已刷了Openwrt的WEB端进行刷入。 https://downloads.openwrt.org/releases/19.07.3/targets/ar71xx/nand/openwrt-19.07.3-ar71xx-nand-wndr4300-ubi-factory.img https://downloads.openwrt.org/releases/17.01.4/targets/ar71xx/nand/lede-17.01.4-ar71xx-nand-wndr4300-squashfs-sysupgrade.tar opkg update opkg install libopenssl opkg list_installed 下载img文件 http://downloads.openwrt.org/chaos_calmer/15.05/ar71xx/nand/openwrt-15.05-ar71xx-nand-wndr4300-ubi-factory.img 进路由器界面,找到『固件升级』,然后上传这个包点确定。路由器就会自动刷成 openwrt 固件,等待它重启后再连路由器就大功告成了。 下载升级包: http://downloads.openwrt.org/chaos_calmer/15.05/ar71xx/nand/openwrt-15.05-ar71xx-nand-wndr4300-squashfs-sysupgrade.tar稍后在 openwrt 系统里给升级。 基础设置 新的 openwrt 固件默认是不开 wifi 的,所以第一次你得用网线连上路由器,进去后应试能看到 luci 界面,这里会让你输入密码,用户名默认是 root,此时密码还是个空的,随便输一个回车进回界面, 先设置一密码吧,直接点 luci 界面上面的警告条后进入密码设置界面,输入一个你自己的密码,顺便把下面的 远程ssh给勾上。 让你的路由器连上网,按顶部菜单栏进入net-interface选择你的接口,通常是 WAN 口,点旁边的 eidt,然后选择 ppope,点切换,然后输入你的宽带帐号和密码,然后应用。 此时你的路由已经能上网了。 https://wiki.openwrt.org/zh-cn/toh/netgear/wndr4300 http://dlmao.com/wndr4300-%E6%8A%98%E8%85%BE-openwrt-%E8%AE%B0.html http://dlmao.com/wndr4300-zhe-teng-openwrt-ji-zhong-ji-xiu-zheng-ban.html https://bigeagle.me/2016/02/ipset-policy-routing/ https://php-rmcr7.rhcloud.com/openwrt-fq/ https://php-rmcr7.rhcloud.com/openwrt-fq/embed/#?secret=xcThHfkyLS https://cokebar.info/archives/948 https://cokebar.info/archives/948/embed#?secret=k8dinHiD9m https://forum.archive.openwrt.org/viewtopic.php?id=16599

2016-01-09 · 1 min · 76 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 · -

python property

python @property 在绑定属性时,如果我们直接把属性暴露出去,虽然写起来很简单,但是,没办法检查参数,导致可以把成绩随便改: s = Student() s.score = 9999 这显然不合逻辑。为了限制score的范围,可以通过一个set_score()方法来设置成绩,再通过一个get_score()来获取成绩,这样,在set_score()方法里,就可以检查参数: class Student(object): def get_score(self): return self._score def set_score(self, value): if not isinstance(value, int): raise ValueError('score must be an integer!') if value < 0 or value > 100: raise ValueError('score must between 0 ~ 100!') self._score = value 现在,对任意的Student实例进行操作,就不能随心所欲地设置score了: s = Student() s.set_score(60) # ok! s.get_score() 60 s.set_score(9999) Traceback (most recent call last): … ValueError: score must between 0 ~ 100! 但是,上面的调用方法又略显复杂,没有直接用属性这么直接简单。 ...

2016-01-06 · 1 min · 206 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 · -

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 · -

tightvnc, tigervnc

tightvnc, tigervnc tighervnc nightly build https://github.com/TigerVNC/tigervnc/releases http://tigervnc.bphinz.com/nightly/ # archlinux pacman -S tigervnc # vncserver # dell desktop vncserver -geometry 1350x670 -dpi 96 -depth 32 :1 vncserver -geometry 1364x768 -dpi 96 -depth 32 :1 vncserver -kill :1 #kill 后面有空格!!! vncviewer 192.168.2.228:1 #edis config file .vnc/xstartup #!/bin/sh startxfce4 exit full screen ctrl+alt+shift+F vncviewer: disable allow jpeg https://unix.stackexchange.com/questions/67096/xterm-warning-tried-to-connect-to-session-manager centos yum -y install tigervnc-server yum -y install tigervnc install xorg start xorg install xfce4 ...

2015-12-25 · 1 min · 74 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 · -

Paxos

Paxos paxos Paxos (Greek: Παξοί, pronounced Paksi in English ) 又名Paxi是希腊西南部一个风景如画的小岛。而Paxos算法则是现在很火的分布式一致性算法,为何以一个希腊小岛名字算法?Lamport这样解释道: I thought, and still think, that Paxos is an important algorithm. Inspired by my success at popularizing the consensus problem by describing it with Byzantine generals, I decided to cast the algorithm in terms of a parliament on an ancient Greek island. Leo Guibas suggested the name Paxos for the island. 为描述 Paxos 算法,Lamport 虚拟了一个叫做 Paxos 的希腊城邦,这个岛按照议会民主制的政治模式制订法律,但是没有人愿意将自己的全部时间和精力放在这种事情上。所以无论是议员,议长或者传递纸条的服务员都不能承诺别人需要时一定会出现,也无法承诺批准决议或者传递消息的时间。但是这里假设没有拜占庭将军问题 (Byzantine failure,即虽然有可能一个消息被传递了两次,但是绝对不会出现错误的消息) ;只要等待足够的时间,消息就会被传到。另外,Paxos 岛上的议员是不会反对其他议员提出的决议的[1]。 ...

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

Zookeeper

Zookeeper ZooKeeper 是 Hadoop 的一个子项目,一般用来管理较大规模、结构复杂的服务器集群,具有自己的配置文件语法、管理工具和部署模式 分布式的K/V存储 分布式协调系统 微服务注册中心 服务发现 zookeeper 起源于 Hadoop 生态系统 zookeeper 使用 ZAB 协议作为其一致性协议 znode 只能存1M以内的数据 写入性能低, 为保证一致性, 每次需要n/2+1的写入完成才算完成 zookeeper 的数据是全部存储在内存, 只适合存元数据 Zookeeper 的使用场景是有高一致性的 集群模式 Zookeeper 不仅可以单机提供服务,同时也支持多机组成集群来提供服务。实际上 Zookeeper 还支持另外一种伪集群的方式,也就是可以在一台物理机上运行多个 Zookeeper 实例,下面将介绍集群模式的安装和配置。 Zookeeper 的集群模式的安装和配置也不是很复杂,所要做的就是增加几个配置项。集群模式除了上面的三个配置项还要增加下面几个配置项: initLimit=5 syncLimit=2 server.1=192.168.211.1:2888:3888 server.2=192.168.211.2:2888:3888 initLimit: 这个配置项是用来配置 Zookeeper 接受客户端 (这里所说的客户端不是用户连接 Zookeeper 服务器的客户端,而是 Zookeeper 服务器集群中连接到 Leader 的 Follower 服务器) 初始化连接时最长能忍受多少个心跳时间间隔数。当已经超过 10 个心跳的时间 (也就是 tickTime) 长度后 Zookeeper 服务器还没有收到客户端的返回信息,那么表明这个客户端连接失败。总的时间长度就是 5_2000=10 秒 syncLimit: 这个配置项标识 Leader 与 Follower 之间发送消息,请求和应答时间长度,最长不能超过多少个 tickTime 的时间长度,总的时间长度就是 2_2000=4 秒 ...

2015-12-23 · 4 min · 678 words · -

Java cpu 占用调查

Java cpu 占用调查 获取Java进程的PID jcmd -l 查看某一个进程的哪个线程占用 CPU 过高 top -H -p <PID> ps -mp <PID> -o THREAD,tid,time | sort -rn | head -n 10 打印进程的堆栈信息 jcmd <PID> Thread.print > stack.txt # 或 jstack <PID> stack.txt 将线程的PID转换为16进制 echo "obase=16; PID" | bc printf "%x\n" 73658 在第二步导出的 stack.txt 中查找转换成为16进制的线程PID。找到对应的线程栈 分析负载高的线程栈都是什么业务操作。优化程序并处理问题。 SystemTap,LatencyTOP,vmstat, sar, iostat, top, tcpdump iftop, iptraf, ntop, tcpdump Java的JProfiler/TPTP/CodePro Profiler 性能调优攻略 https://coolshell.cn/articles/7490.html/embed#?secret=sGuaIXdcl5 https://www.linuxhot.com/java-cpu-used-high.html https://linux.cn/article-5633-1.html

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

MySQL 大表 优化

MySQL 大表 优化 作者: zhuqz 链接: https://www.zhihu.com/question/19719997/answer/81930332 来源: 知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 第一优化你的sql和索引; 第二加缓存,memcached,redis; 第三以上都做了后,还是慢,就做主从复制或主主复制,读写分离,可以在应用层做,效率高,也可以用三方工具,第三方工具推荐360的atlas,其它的要么效率不高,要么没人维护; 第四如果以上都做了还是慢,不要想着去做切分,MySQL自带分区表,先试试这个,对你的应用是透明的,无需更改代码,但是sql语句是需要针对分区表做优化的,sql条件中要带上分区条件的列,从而使查询定位到少量的分区上,否则就会扫描全部分区,另外分区表还有一些坑,在这里就不多说了; 第五如果以上都做了,那就先做垂直拆分,其实就是根据你模块的耦合度,将一个大的系统分为多个小的系统,也就是分布式系统; 第六才是水平切分,针对数据量大的表,这一步最麻烦,最能考验技术水平,要选择一个合理的sharding key,为了有好的查询效率,表结构也要改动,做一定的冗余,应用也要改,sql中尽量带sharding key,将数据定位到限定的表上去查,而不是扫描全部的表; MySQL数据库一般都是按照这个步骤去演化的,成本也是由低到高;有人也许要说第一步优化sql和索引这还用说吗?的确,大家都知道,但是很多情况下,这一步做的并不到位,甚至有的只做了根据sql去建索引,根本没对sql优化 (中枪了没?) ,除了最简单的增删改查外,想实现一个查询,可以写出很多种查询语句,不同的语句,根据你选择的引擎、表中数据的分布情况、索引情况、数据库优化策略、查询中的锁策略等因素,最终查询的效率相差很大;优化要从整体去考虑,有时你优化一条语句后,其它查询反而效率被降低了,所以要取一个平衡点;即使精通MySQL的话,除了纯技术面优化,还要根据业务面去优化sql语句,这样才能达到最优效果;你敢说你的sql和索引已经是最优了吗?再说一下不同引擎的优化,myisam读的效果好,写的效率差,这和它数据存储格式,索引的指针和锁的策略有关的,它的数据是顺序存储的 (innodb数据存储方式是聚簇索引) ,他的索引btree上的节点是一个指向数据物理位置的指针,所以查找起来很快, (innodb索引节点存的则是数据的主键,所以需要根据主键二次查找) ;myisam锁是表锁,只有读读之间是并发的,写写之间和读写之间 (读和插入之间是可以并发的,去设置concurrent_insert参数,定期执行表优化操作,更新操作就没有办法了) 是串行的,所以写起来慢,并且默认的写优先级比读优先级高,高到写操作来了后,可以马上插入到读操作前面去,如果批量写,会导致读请求饿死,所以要设置读写优先级或设置多少写操作后执行读操作的策略;myisam不要使用查询时间太长的sql,如果策略使用不当,也会导致写饿死,所以尽量去拆分查询效率低的sql,innodb一般都是行锁,这个一般指的是sql用到索引的时候,行锁是加在索引上的,不是加在数据记录上的,如果sql没有用到索引,仍然会锁定表,MySQL的读写之间是可以并发的,普通的select是不需要锁的,当查询的记录遇到锁时,用的是一致性的非锁定快照读,也就是根据数据库隔离级别策略,会去读被锁定行的快照,其它更新或加锁读语句用的是当前读,读取原始行;因为普通读与写不冲突,所以innodb不会出现读写饿死的情况,又因为在使用索引的时候用的是行锁,锁的粒度小,竞争相同锁的情况就少,就增加了并发处理,所以并发读写的效率还是很优秀的,问题在于索引查询后的根据主键的二次查找导致效率低;ps:很奇怪,为什innodb的索引叶子节点存的是主键而不是像mysism一样存数据的物理地址指针吗?如果存的是物理地址指针不就不需要二次查找了吗,这也是我开始的疑惑,根据mysism和innodb数据存储方式的差异去想,你就会明白了,我就不费口舌了!所以innodb为了避免二次查找可以使用索引覆盖技术,无法使用索引覆盖的,再延伸一下就是基于索引覆盖实现延迟关联;不知道什么是索引覆盖的,建议你无论如何都要弄清楚它是怎么回事!尽你所能去优化你的sql吧!说它成本低,却又是一项费时费力的活,需要在技术与业务都熟悉的情况下,用心去优化才能做到最优,优化后的效果也是立竿见影的!

2015-12-22 · 1 min · 27 words · -