慢查询优化

慢查询优化 https://tech.meituan.com/MySQL-index.html 慢查询优化基本步骤 0.先运行看看是否真的很慢,注意设置SQL_NO_CACHE 1.where条件单表查,锁定最小返回记录表。这句话的意思是把查询语句的where都应用到表中返回的记录数最小的表开始查起,单表每个字段分别查询,看哪个字段的区分度最高 2.explain查看执行计划,是否与1预期一致 (从锁定记录较少的表开始查询) 3.order by limit 形式的sql语句让排序的表优先查 4.了解业务方使用场景 5.加索引时参照建索引的几大原则 6.观察结果,不符合预期继续从0分析 Using filesort MySQL must do an extra pass to find out how to retrieve the rows in sorted order. The sort is done by going through all rows according to the join type and storing the sort key and pointer to the row for all rows that match the WHERE clause. Using temporary,表示需要创建临时表以满足需求,通常是因为GROUP BY的列没有索引,或者GROUP BY和ORDER BY的列不一样,也需要创建临时表,建议添加适当的索引。 ...

2017-11-22 · 1 min · 87 words · -

MySQL using having

MySQL using having http://wuzhangshu927.blog.163.com/blog/static/1142246872010113093426574/ USING() using 可用在 join 语句相同字段连接, 起到和 ON 相同作用, inner join 和 left join 中都可以使用 LEFT JOIN 正常写法: SELECT t1.id,t2.name FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE .... 其实也可以这么写: SELECT t1.id,t2.name FROM t1 LEFT JOIN t2 USING(id) WHERE .... HAVING MySQL 中的 where 和 having 子句都可以实现筛选记录的功能, having 可以认为是对 where 的补充, 因为它可以对分组数据进行再次判断, 一般跟在 group by 后面, 并可以使用聚集函数 (sum, min, max, avg, count) SELECT `uid`, SUM(`points`) num FROM table GROUP BY `uid` HAVING num > 1000

2017-11-22 · 1 min · 78 words · -

go xml

go xml https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/07.1.md

2017-11-21 · 1 min · 3 words · -

Linux磁盘分区UUID, blkid

Linux 磁盘分区 UUID, blkid http://tiger2020.blog.51cto.com/723949/1535774 查看设备的 uuid 的三种方法, 总结如下: 1 命令查看: blkid 2 文件查看: ls -l /dev/disk/by-uuid 3 命令查看: vol_id /dev/sda1 UUID的作用及意义 1: 它是真正的唯一标志符 UUID为系统中的存储设备提供唯一的标识字符串,不管这个设备是什么类型的。如果你在系统中启动的时候,使用盘符挂载时,可能找不到设备而加载失败,而使用UUID挂载时,则不会有这样的问题。 2: 设备名并非总是不变的 自动分配的设备名称并非总是一致的,它们依赖于启动时内核加载模块的顺序。如果你在插入了USB盘时启动了系统,而下次启动时又把它拔掉了,就有可能导致设备名分配不一致。 使用UUID对于挂载移动设备也非常有好处,它支持各种各样的卡,而使用UUID总可以使同一块卡挂载在同一个地方。 3: Ubuntu中的许多关键功能现在开始依赖于UUID

2017-11-19 · 1 min · 31 words · -

golang select

golang select package main import ( "fmt" "time" ) func main() { fmt.Println("selectx") ch0 := make(chan struct{}) ch1 := make(chan struct{}) go func() { for { select { case v0 := <-ch0: fmt.Println("ch0: ", v0) case v1 := <-ch1: fmt.Println("ch1: ", v1) } } }() time.Sleep(1 * time.Second) ch0 <- struct{}{} ch1 <- struct{}{} ch0 <- struct{}{} ch1 <- struct{}{} ch1 <- struct{}{} ch1 <- struct{}{} time.Sleep(3 * time.Second) fmt.Println("selectx end") } // output: // ch0: {} // ch1: {} // ch0: {} // ch1: {} // ch1: {} // ch1: {} 代码执行到 select 时默认会阻塞, 直到任意一个 case 评估通过, 如果有多个 case 符合执行条件就从里面随机选一个执行. ...

2017-11-17 · 2 min · 386 words · -

PAM(Pluggable Authentication Modules)

PAM(Pluggable Authentication Modules) auth: 表示鉴别类接口模块类型用于检查用户和密码,并分配权限; account: 表示账户类接口,主要负责账户合法性检查,确认帐号是否过期,是否有权限登录系统等; session: 会话类接口。实现从用户登录成功到退出的会话控制; password: 口令类接口。控制用户更改密码的全过程。也就是有些资料所说的升级用户验证标记。 system-auth文件是PAM模块的重要配置文件,它主要负责用户登录系统的身份认证工作,不仅如此,其他的应用程序或服务可以通过include接口来调用它 (该文件是system-auth-ac的软链接) 。此外password-auth配置文件也是与身份验证相关的重要配置文件,比如用户的远程登录验证(SSH登录)就通过它调用。而在Ubuntu、SuSE Linux等发行版中,PAM主要配置文件是common-auth、common-account、common-password、common-session这四个文件,所有的应用程序和服务的主要PAM配置都可以通过它们来调用。 http://www.infoq.com/cn/articles/linux-pam-one Linux中pam_cracklib.so的minlen和credit参数 Linux中的PAM(Pluggable Authentication Modules)包含很多有用的模块,其中pam_cracklib.so模块可以配置密码长度复杂度的需求。一般需要同时配置/etc/pam.d/目录中的system-auth和password-auth文件,例如下面 password requisite pam_cracklib.so try_first_pass retry=3 type= ocredit=2 minlen=10 限定密码长度主要涉及minlen参数,以及ucredit lcredit dcredit ocredit这四个credit参数,分别表示大写字符、小写字符、数字、其它字符的额外credit值。 这里的minlen=10实际上表示最小分数为10,而不是简单的最小长度为10。密码每有一个任意字符会有一分,另外,ucredit/lcredit/dcredit/ocredit默认值均为1,表示密码中四种字符的类别数,每多一种,就会得到额外的一分。 在这里,ocredit=2 minlen=10,也就是说,如果密码全是其它字符的话,最少需要minlen - ocredit = 10-2 = 8位;若密码包含其它字符和小写字符,最少需要minlen - ocredit - lcredit = 10-2-1 = 7位字符,以此类推。 另外ucredit/lcredit/dcredit/ocredit参数的值如果为负数,例如dcredit=-2,则表示密码中最少需要2位数字。 另外,除了密码长度之外,pam_cracklib.so库默认还会做其它方面的简单检查,并且库代码里写死了密码最小长度不能小于6. reference http://www.deer-run.com/~hal/sysadmin/pam_cracklib.html http://www.infoq.com/cn/articles/linux-pam-one

2017-11-14 · 1 min · 54 words · -

partx

partx http://gulingzi.blog.51cto.com/2208376/1561403 /proc/partitions 记录了系统中所有硬盘及其上面的分区,包括已挂载和未挂载的。 有些硬盘没有记录分区信息,可能是没有分区,或者未记录 对于分区完成,但是尚未挂载的硬盘分区,partx告诉内核去做登记,以备挂载。 partx 告诉内核去识别、登记某个硬盘上的分区信息。并不是加载,只是识别并记录而已。 或者删除某个分区的记录。 -a 登记某块盘上的所有分区信息,如果某个分区信息已有记录,就会报错: BLKPG: Device or resource busy error adding partition 4 如果某磁盘上的分区信息都没有被记录,则安静完成。 -d 删除内核中关于某磁盘上的所有分区的记录 (不是卸载) -d -nr m-n 删除从第m-n分区的记录 如果已经挂载,则无法删除,并报错: error deleting partition 5: BLKPG: Device or resource busy 如果都删除了,使用-a选项来重新登记,不会有报错。 一般分区完成后,系统会识别到。 -l 列出某磁盘上的分区情况。数据从磁盘上获取,并不是来源于/proc/partitions

2017-11-13 · 1 min · 42 words · -

prototype

prototype 基于原型编程是面向对象编程的一种方式, 原型编程里没有 class 的概念, 直接使用对象, 又叫基于实例的编程. 基于类的编程中, 类定义了对象的基本布局和函数特性, 接口是可以使用的对象, 它基于特定类样式. 类表现为行为和结构的集合, 对接口来说这些类的行为和结构是想同的. 区分的规则是基于行为和结构之后才是状态.

2017-11-13 · 1 min · 14 words · -

System V init, Upstart,Systemd

System V init, Upstart,Systemd http://monklof.com/post/14/ https://www.ibm.com/developerworks/cn/linux/1407_liuming_init2/index.html

2017-11-10 · 1 min · 6 words · -

city

city Amsterdam, Netherlands, 荷兰 Bangalore, India london ottawa 加拿大.渥太华 Richardson,Texas,US RTP,US 北卡 sanjose,California,US 圣荷西 shanghai sigapore sydney telaviv 特拉维夫 tokyo

2017-11-10 · 1 min · 20 words · -

Round Robin 轮询调度算法

Round Robin 轮询调度算法 Round Robin Scheduling 轮询调度算法 轮询调度 (Round Robin Scheduling) 算法就是以轮询的方式依次将请求调度不同的服务器,即每次调度执行i = (i + 1) mod n,并选出第i台服务器。算法的优点是其简洁性,它无需记录当前所有连接的状态,所以它是一种无状态调度。 轮询调度算法的原理是每一次把来自用户的请求轮流分配给内部中的服务器,从1开始,直到N(内部服务器个数),然后重新开始循环。 轮询调度算法假设所有服务器的处理性能都相同,不关心每台服务器的当前连接数和响应速度。当请求服务间隔时间变化比较大时,轮询调度算法容易导致服务器间的负载不平衡。 所以此种均衡算法适合于服务器组中的所有服务器都有相同的软硬件配置并且平均服务请求相对均衡的情况。 作者: 小程故事多 链接: http://www.jianshu.com/p/92666209041a 來源: 简书 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 负载均衡调度算法默认是 round robin,也就是轮询调度算法。 算法本身很简单,轮着一个一个来,非常简单高效公平的调度算法。 突然发现了一直被忽视的问题,为啥叫 round robin ? robin 明明是旅鸫,亦称美洲知更鸟,与轮询一点关系都没有。在查询资料后发现这个单词来源挺有意思的,这里分享给大家。 round robin 来源于法语ruban rond (round ribbon) ,意思是环形丝带。 在17、18世纪时法国农民希望以请愿的方式抗议国王时,通常君主的反应是将请愿书中最前面的两至三人逮捕并处决,所以很自然地没有人希望自己的名字被列在前面。为了对付这种专制的报复,人们在请愿书底部把名字签成一个圈 (如同一条环状的带子) ,这样就找不出带头大哥,于是只能对所有参与者进行同样的惩罚。 1731年,英国皇家海军最初使用了这个名词,以循环顺序签署请愿书,这样就没法找到带头大哥了。 非常贴切有木有,后端服务器轮着来处理请求,一个个都不要抢,都要出来接受处决。 https://zhuanlan.zhihu.com/p/84799744 常见的负载均衡算法包含: 轮询法 (Round Robin) 加权轮询法 (Weight Round Robin) 随机法 (Random) 加权随机法 (Weight Random) 平滑加权轮询法 (Smooth Weight Round Robin) 源地址哈希法 (Hash) 最小连接数法 (Least Connections) ———————————————— 版权声明: 本文为CSDN博主「志波同学」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接: https://blog.csdn.net/claram/article/details/90265243

2017-11-10 · 1 min · 81 words · -

go channel

go channel channel 是 Go 中的一个核心类型, 可以把它看成一个管道, 通过它并发核心单元就可以发送或者接收数据进行通讯。goroutine 是 Go 语言的基本调度单位, 而 channels 则是它们之间的通信机制。操作符 <- 用来指定管道的方向,发送或接收。如果未指定方向,则为双向管道。golang 的 channel 就是一个 环形队列/ringbuffer 的实现。 我们称 chan 为管理结构,channel 里面可以放任何类型的对象,我们称之为元素。 Channel 定义 ChannelType = ( "chan" | "chan<-" | "<-chan" ) ElementType . 可选的 <- 代表 channel 的方向 (是数据的流向)。如果没有指定方向,那么 Channel 就是双向的,既可以接收数据,也可以发送数据。 <- // channel 的操作符 ch <- v // 发送值 v 到 Channel ch 中 v := <-ch // 从 Channel ch 中接收数据, 并将数据赋值给 v var foo chan T // 可以接收和发送类型为 T 的数据 var foo chan<- float64 // 只可以用来发送 float64 类型的数据 var foo <-chan int // 只可以用来接收 int 类型的数据 // <- 总是优先和最左边的类型结合。(The <- operator associates with the leftmost chan possible) chan<- chan int // 等价 chan<- (chan int) chan<- <-chan int // 等价 chan<- (<-chan int) <-chan <-chan int // 等价 <-chan (<-chan int) chan (<-chan int) // channel 定义 var dataChan <-chan []byte // 无缓冲的 channel // 使用 make 初始化 Channel, 并且可以设置容量, channel 初始化, 初始化之后才能使用 // 未设置容量的 channel, 如果没有设置容量,或者容量设置为0, 说明Channel没有缓存,只有sender和receiver都准备好了后它们的通讯 // 无缓冲的 channel 由于没有缓冲发送和接收需要同步. // channel 无缓冲时,发送阻塞直到数据被接收,接收阻塞直到读到数据。 dataChan := make(<-chan []byte) // 容量为100的 channel ch := make(chan int, 100) // 容量(capacity)代表Channel容纳的最多的元素的数量,代表Channel的缓存的大小。 // 创建一个双向channel, interface{}表示chan可以为任何类型 foo := make(chan interface{}) // 可以通过内建的close方法可以关闭Channel。 close(foo) // channel的 receive支持 multi-valued assignment,如 v, ok := <-ch 往一个已经被 close 的 channe l中继续发送数据会导致 run-time panic。 ...

2017-11-09 · 3 min · 450 words · -

nginx模块

nginx模块 http://wiki.jikexueyuan.com/project/nginx/model-architecture.html event module: 搭建了独立于操作系统的事件处理机制的框架,及提供了各具体事件的处理。包括 ngx_events_module, ngx_event_core_module和ngx_epoll_module 等。Nginx 具体使用何种事件处理模块,这依赖于具体的操作系统和编译选项。 phase handler: 此类型的模块也被直接称为 handler 模块。主要负责处理客户端请求并产生待响应内容,比如 ngx_http_static_module 模块,负责客户端的静态页面请求处理并将对应的磁盘文件准备为响应内容输出。 output filter: 也称为 filter 模块,主要是负责对输出的内容进行处理,可以对输出进行修改。例如,可以实现对输出的所有 html 页面增加预定义的 footbar 一类的工作,或者对输出的图片的 URL 进行替换之类的工作。 upstream: upstream 模块实现反向代理的功能,将真正的请求转发到后端服务器上,并从后端服务器上读取响应,发回客户端。upstream 模块是一种特殊的 handler,只不过响应内容不是真正由自己产生的,而是从后端服务器上读取的。 load-balancer: 负载均衡模块,实现特定的算法,在众多的后端服务器中,选择一个服务器出来作为某个请求的转发服务器。

2017-11-08 · 1 min · 34 words · -

事件驱动服务器, event-driven server

事件驱动服务器, event-driven server https://gist.github.com/jcouyang/9914091 OPPC模型瓶颈 传统服务器模型如Apache为每一个请求生成一个子进程。当用户连接到服务器的一个子进程就产生,并处理连接。每个连接获得一个单独的线程和子进程。当用户请求数据返回时,子进程开始等待数据库操作返回。如果此时另一个用户也请求返回数据,这时就产生了阻塞。 这种模式在非常小的工作负荷是表现良好,当请求的数量变得太大是服务器会压力过于巨大。 当Apache达到进程的最大数量,所有进程都变得缓慢。每个请求都有自己的线程,如果服务代码使用PHP编写时,每个进程所需要的内存量是相当大的[1]。 fork()操作延时 事实上,基于OPPC的网络并不如想象中的高效。首先新建进程的性能很大程度上依赖于操作系统对fork()的实现,然而不同操作系统的处理并非都理想。 操作系统fork操作只是简单的拷贝分页映射。动态链接为共享库和全局偏移表中的ELF (Executable and Linking Format) 部分创建太多的分页映射。虽然静态的链接fork会是的性能大幅度提升,但是延时依然不乐观。 进程调度 Linux每10毫秒 (Alpha是1毫秒,该值为已编译常量) 中断一次在运行态的进程,查看是否要切换别的进程执行。进程调度的任务就是决定下一个应该执行的进程,而其难度就在于如何公平的分配CPU资源。一个好的调度算法应该给每一个进程都分享公平的CPU资源,而且不应该出现饥饿进程。 Unix系统采用多级反馈队列调度算法。使用多个不同优先级的就绪队列,使用Heap保持队列按优先级顺序排序。Linux 2.6版本提供了一个复杂度O(1)的调度算法,将进程调度延时降至最小。但是进程调度的频率是100Hz,意味着10毫秒会中止一个进程而判断是否需要切换到另一个进程。如果切换过多,会让CPU忙于切换,导致降低吞吐量。 内存占用与线程 创建多进程会带来另外一个问题: 内存消耗。 每一个创建的进程都会占用内存,在 Linux 2.6 中的测试结果, 400个左右的连接后 fork() 的性能要超过 pthread_create() 的性能。 IBM 对 Linux 做过优化后, 一个进程可以处理 10 万个连接。 fork () 在每一个连接时都 fork() 一次成本太高,多线程在于需要考虑线程安全(thread-safe)与死锁(deadlock),以及内存泄露问题这些问题。 可靠性 该模型具有可靠性问题。一个配置不当的服务器,很容易遭受拒绝服务攻击 (DoS) 。当大量并发请求的服务器资源时,负载均衡配置不当时服务器会很快耗尽源而奔溃。 同步阻塞 I/O 在这个模型中,应用程序执行一个系统调用,这会导致应用程序阻塞。这意味着应用程序会一直阻塞,直到系统调用完成为止 (数据传输完成或发生错误) 。调用应用程序处于一种不再占用CPU,而只是简单等待响应的状态,但是该进程依然占用着资源。当大量并发I/O请求到达时,则会产生I/O阻塞,造成服务器瓶颈。 事件驱动模型服务器 通过上诉分析与实验说明,事实上,操作系统并不是设计来处理服务器工作负载。传统的线程模型是基于运行应用程序是的一些密集型操作的需要。 操作系统的设计是让用户执行的多线程程序,使后台文件写入和UI操作同时进行,而并不是设计于处理大量并发请求连接。 Fork和多线程是相当费资源的操作,创建线程需要分配一个全新的内存堆栈。此外,上下文切换也是一项开销的,CPU调度模型是并不太适合一个传统的Web服务器。 因此,OPPC模型面临着多进程多线程的延迟已经内存消耗的问题。要用OPPC模型解决C10K问题显得十分复杂。 为解决C10K问题,一些新的服务器呈现出来。下列是解决C10K问题的Web服务器: nginx: 一个基于事件驱动的处理请求架构反向代理服务器。 Cherokee: Twitter使用的开源Web服务器。 [Tornado][13]: 一个Python语言实现的非阻塞式Web服务器框架。Facebook的FriendFeed模块使用此框架完成。 Node.js: 异步非阻塞Web服务器,运行于Google V8 JavaScript引擎。 ...

2017-11-08 · 2 min · 277 words · -

TPS、QPS、RPS

TPS、QPS、RPS PPS PPS (Packet Per Second) PCT (percentile) PCT99: 99%的响应时间 “90th pct/95th pct/99th pct”分别表示测试实例按响应时间从小到大排序后,第90/95/99个测试实例的响应时间。 95%percentile : 统计学术语,如果将一组数据从小到大排序,并计算相应的累计百分位,则某一百分位所对应数据的值就称为这一百分位的百分位数。可表示为: 一组 n 个观测值按数值大小排列。如,处于 p% 位置的值称第 p 百分位数。 QPS Queries Per Second,每秒查询数。每秒能够响应的查询次数。 QPS是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准,在因特网上,作为域名系统服务器的机器的性能经常用每秒查询率来衡量。每秒的响应请求数,也即是最大吞吐能力。 TPS Transactions Per Second 的缩写,每秒处理的事务数目。一个事务是指一个客户机向服务器发送请求然后服务器做出反应的过程。客户机在发送请求时开始计时,收到服务器响应后结束计时,以此来计算使用的时间和完成的事务个数,最终利用这些信息作出的评估分。 TPS 的过程包括: 客户端请求服务端、服务端内部处理、服务端返回客户端。 例如,访问一个 Index 页面会请求服务器 3 次,包括一次 html,一次 css,一次 js,那么访问这一个页面就会产生一个“T”,产生三个“Q”。 PV (page view) 即页面浏览量,通常是衡量一个网络新闻频道或网站甚至一条网络新闻的主要指标。 PV 即 page view,页面浏览量。用户每一次对网站中的每个页面访问均被记录 1 次。用户对同一页面的多次刷新,访问量累计。 根据这个特性,刷网站的 PV 就很好刷了。 与 PV 相关的还有 RV,即重复访问者数量 (repeat visitors) 。 UV 访问数 (Unique Visitor) 指独立访客访问数,统计1天内访问某站点的用户数(以 cookie 为依据),一台电脑终端为一个访客。 ...

2017-11-08 · 1 min · 183 words · -

java spi, ServiceLoader

java spi, ServiceLoader ServiceLoader与ClassLoader是Java中2个即相互区别又相互联系的加载器.JVM利用ClassLoader将类载入内存,这是一个类声明周期的第一步 (一个java类的完整的生命周期会经历加载、连接、初始化、使用、和卸载五个阶段,当然也有在加载或者连接之后没有被初始化就直接被使用的情况) 。详情请参阅: 详解Java类的生命周期 那ServiceLoader又是什么呢?ServiceLoader: 一个简单的服务提供者加载设施。服务 是一个熟知的接口和类 (通常为抽象类) 集合。服务提供者 是服务的特定实现。提供者中的类通常实现接口,并子类化在服务本身中定义的子类。服务提供者可以以扩展的形式安装在 Java 平台的实现中,也就是将 jar 文件放入任意常用的扩展目录中。也可通过将提供者加入应用程序类路径,或者通过其他某些特定于平台的方式使其可用。……唯一强制要求的是,提供者类必须具有不带参数的构造方法,以便它们可以在加载中被实例化。 通过在资源目录META-INF/services中放置提供者配置文件 来标识服务提供者。文件名称是服务类型的完全限定二进制名称。该文件包含一个具体提供者类的完全限定二进制名称列表,每行一个。忽略各名称周围的空格、制表符和空行。注释字符为’#’(’\u0023’, NUMBER SIGN);忽略每行第一个注释字符后面的所有字符。文件必须使用 UTF-8 编码。 以延迟方式查找和实例化提供者,也就是说根据需要进行。服务加载器维护到目前为止已经加载的提供者缓存。每次调用 iterator 方法返回一个迭代器,它首先按照实例化顺序生成缓存的所有元素,然后以延迟方式查找和实例化所有剩余的提供者,依次将每个提供者添加到缓存。可以通过 reload 方法清除缓存。 …… 以上来源于Java API里的说明,也许说的很专业,让我们有点晕头转向,我们可以简单的认为: ServiceLoader也像ClassLoader一样,能装载类文件,但是使用时有区别,具体区别如下: (1) ServiceLoader装载的是一系列有某种共同特征的实现类,而ClassLoader是个万能加载器; (2) ServiceLoader装载时需要特殊的配置,使用时也与ClassLoader有所区别; (3) ServiceLoader还实现了Iterator接口。[如有错误或不到的地方敬请指出,互相学习: ) ] SPI 和 ServiceLoader 1 SPI: Service Provider Interface 一个服务(Service)通常指的是已知的接口或者抽象类,服务提供方就是对这个接口或者抽象类的实现,然后按照SPI 标准存放到资源路径META-INF/services目录下,文件的命名为该服务接口的全限定名 许多开发框架都使用了Java的SPI机制,如java.sql.Driver的SPI实现 (MySQL驱动、oracle驱动等) 、common-logging的日志接口实现、dubbo的扩展实现等等。 我们系统里抽象的各个模块,往往有很多不同的实现方案,比如日志模块的方案,xml解析模块、jdbc模块的方案等。面向的对象的设计里,我们一般推荐模块之间基于接口编程,模块之间不对实现类进行硬编码。一旦代码里涉及具体的实现类,就违反了可拔插的原则,如果需要替换一种实现,就需要修改代码。 为了实现在模块装配的时候能不在程序里动态指明,这就需要一种服务发现机制。java spi就是提供这样的一个机制: 为某个接口寻找服务实现的机制。有点类似IOC的思想,就是将装配的控制权移到程序之外,在模块化设计中这个机制尤其重要。 java spi的具体约定如下: 当服务的提供者,提供了服务接口的一种实现之后,在jar包的META-INF/services/目录里同时创建一个以服务接口命名的文件。该文件里就是实现该服务接口的具体实现类。而当外部程序装配这个模块的时候,就能通过该jar包META-INF/services/里的配置文件找到具体的实现类名,并装载实例化,完成模块的注入 1.例子 第一步: 提供一个接口和它的若干个实现: 有一个接口 package com.xihe.api; public interface XiheInterface { public void sayHi(); ...

2017-11-07 · 1 min · 166 words · -

spring rabbitmq

spring rabbitmq https://spring.io/guides/gs/messaging-rabbitmq/

2017-11-05 · 1 min · 3 words · -

raspberry ntp

raspberry ntp http://raspberrypi.tomasgreno.cz/ntp-client-and-server.html

2017-10-31 · 1 min · 3 words · -

linux enca 编码并转换

linux enca 编码并转换 enca -list languages enca -L zh_CN file 检查文件的编码 enca -L zh_CN -x UTF-8 file 将文件编码转换为"UTF-8″编码 enca -L zh_CN -x UTF-8 < file1 > file2 如果不想覆盖原文件可以这样 enca -L none file.txt http://os.51cto.com/art/201007/214344.htm http://www.shenyanchao.cn/blog/2014/11/13/encode-convert-in-linux/ http://54im.com/tag/enca

2017-10-31 · 1 min · 35 words · -

Mahonia

Mahonia Mahonia—a character-set conversion library for Go Mahonia is a character-set conversion library implemented in Go. All data is compiled into the executable; it doesn’t need any external data files. Mahonia is now deprecated. I recommend using the standard package at golang.org/x/text/encoding, possibly along with golang.org/x/net/charset https://code.google.com/archive/p/mahonia/

2017-10-31 · 1 min · 47 words · -