创建 redis systemd 服务

服务器操作系统一直使用的是 ubuntu server,因为安装软件很方便,直接apt-get install就行。但使用 apt 安装 redis 版本比较旧,也没有新的源,所有只能自己编译安装了。不过有个问题,自己编译安装的启动和重启比较麻烦(启动:/usr/bin/redis-server /etc/redis/redis.conf,停止:/usr/bin/redis-cli shutdown)。我在想能不能使用类似 ubuntu service xxx restart 的指令。

搜索了一下发现可以使用upstart来实现这个需求,但是这个在 ubuntu 15.04 已经废弃了,推荐使用更先进的systemd。在 /etc/systemd/system/ 下创建一个 redis.service:

其中主要是定义了启动用户,启动命令,停止命令。有个设置比较重要Type=forking,可以理解为 systemd 是一个类似 supervise 的守护进程,forking 表示服务管理器是系统 init 的子进程,用于管理需要后台运行的服务。同时还需要修改 redis 的配置:

然后就可以使用sudo systemctl start redis命令启动 redis 了。同时支持 stop、restart 等常用指令。启动成功后运行 sudo systemctl status redis查看运行状态:

可以看见 redis 已经正常运行了。可以尝试使用 kill -9 命令把 redis 杀死,你会发现 redis 马上又会被拉起,这样能保证服务能一直运行(当然若是服务有问题一直蹦,谁也救不了你)。若需要开机启动还可以运行sudo systemctl enable redis命令加入到开启启动项里面。

我们平常自己写的程序也可以依样画葫芦写个配置文件,使用 systemctl 来做服务管理,这种方式更加先进,还有一些其它实用的功能。

 

参考资料:

Ubuntu systemd service file for Redis, https://gist.github.com/geschke/ab6afa91b2d9dfcd5c25

systemd – ArchWiki, https://wiki.archlinux.org/index.php/Systemd

How To Install and Configure Redis on Ubuntu 16.04 | DigitalOcean, https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-redis-on-ubuntu-16-04

PHP单元测试-mock和数据库测试

在计算机编程中,单元测试(英语:Unit Testing)又称为模块测试, 是针对程序模块(软件设计的最小单位)来进行正确性检验的测试工作。程序单元是应用的最小可测试部件。在过程化编程中,一个单元就是单个程序、函数、过程等;对于面向对象编程,最小单元就是方法,包括基类(超类)、抽象类、或者派生类(子类)中的方法。

本文主要是根据PHPUnit(The PHP Testing Framework)文档结合实例简单介绍一下 PHP 单元测试中 mock 和数据库测试。如果你是初次接触单测的话建议先看一下 PHPUnit 文档中的入门章节

通常来说是开发程序和单测是同步进行的,项目提测的时候核心模块都需要包括单测(报告),但这个要求在不同的公司、部门、项目组要求不一样。虽然单测会占用一定的开发时间但总的来说单测是利远大于弊,最大的好处是自己或者别人后续更新模块功能时不用担心对原有功能造成了影响而不知情。

下面是一个具体的例子,在 web 开发中这样一个场景可能很常见:PHP 提供一个帐号注册的接口供前端调用,接口先检验一下此用户名是否已经存在,不存在的话插入数据库,返回注册成功。接口代码是这样的:

主要调用了 Join 类的 signIn 方法。我们来看看 Join 类是啥样:

逻辑很简单,先调用 Db 类的 exists 方法判断用户名是否存在,不存在的话使用 insert 方法插入数据。Join 类是这次业务新加的,比较重要,需要单测来保障质量,但这里用到了个 Db 类,这个库是以前就有的(坑),可能会影响本模块单测的正确性,而且 Db 类需要连接数据库,比较麻烦,这种场景就需要 mock 了。本文说的 mock 是广义上的,包括 Stubs(桩件)和仿件对象(Mock Object)。

将对象替换为(可选地)返回配置好的返回值的测试替身的实践方法称为上桩(stubbing)。可以用桩件(stub)来“替换掉被测系统所依赖的实际组件,这样测试就有了对被测系统的间接输入的控制点。这使得测试能强制安排被测系统的执行路径,否则被测系统可能无法执行”。

将对象替换为能验证预期行为(例如断言某个方法必会被调用)的测试替身的实践方法称为模仿(mocking)

我们这里应用的是打桩的概念。signIn 方法有两个分支:用户名存在和不存在。所以我们需要让 Db 类的 exists 方法在输入某个(些)用户名的时候返回 true。主要使用 PHPUnit_Framework_TestCase 类提供的 getMockBuilder() 方法来建立一个桩件对象:

代码看上去很像是实例化了一个类,其实原理也和这个差不多,PHPUnit 通过反射机制获取到类及其方法的信息,然后使用内置模板生成一个新类。我们需要 mock 掉 insertexists 方法:

这里使用了桩件生成器的 setMethods() 方法来设置哪些方法被上桩,以下是生成器提供的方法列表:

  • setMethods(array $methods) 可以在仿件生成器对象上调用,来指定哪些方法将被替换为可配置的测试替身。其他方法的行为不会有所改变。如果调用 setMethods(null),那么没有方法会被替换。
  • setConstructorArgs(array $args) 可用于向原版类的构造函数(默认情况下不会被替换为伪实现)提供参数数组。
  • setMockClassName($name) 可用于指定生成的测试替身类的类名。
  • disableOriginalConstructor() 参数可用于禁用对原版类的构造方法的调用。
  • disableOriginalClone() 可用于禁用对原版类的克隆方法的调用。
  • disableAutoload()可用于在测试替身类的生成期间禁用 __autoload()

然后分别设置两个方法的参数和返回值。这里 insert 操作比较简单,可以用 willReturn($value) 返回简单值:

上面的例子中,使用了 willReturn($value) 返回简单值。这个简短的语法相当于 will($this->returnValue($value))。而在这个长点的语法中,可以使用变量,从而实现更复杂的上桩行为。我们这里的需求是需要根据预定义的参数清单来返回不同的值,显然这是一个映射(map),PHPUnit 提供现成的 returnValueMap() 方法来做这个事情:

完整的单测代码: Continue Reading…

【译】简单介绍通过Predis库在PHP中使用Redis

本文翻译自 《An Introduction to Redis in PHP using Predis》,已得到作者 @Daniel Gafitescu 的允许。原文版权归作者和 sitepoint.com 所有,如果你有原文使用需求请自行联系作者。

Redis 是一个开源的内存数据库服务器,得益于内建的数据类型,Redis 不仅仅只能做简单的 key/value 存储。

Redis 由 @Salvatore Sanfilippo 在 2009 年发布,因为其受欢迎和增长迅速,被很多大公司比如 VMware(后来聘请作者去全职工作)、GitHub、Craigslist、Disqus、Digg、Blizzard、Instagram 等(详见:redis.io/topics/whos-using-redis)使用。

你可以使用 Redis 做会话(session)处理程序,当你使用负载均衡的分布式服务时特别有用。Redis 也可以用作发布/订阅系统,很优雅的创建一个在线聊天或者实时订购程序。关于 Redis 的文档,所有的命令以及其它信息都能在项目网站 redis.io 上找到。

一直以来都有 Redis 和 Memcache 哪个更好的争论,文章 as the benchmarks show 显示在相同的基础操作上两者不相上下。Redis 比 Memcache 有更多的特性,比如内存存储、磁盘持久化、原子操作、事务以及不用记录每一次变化到磁盘上而是用服务端的数据结构来代替。

在这篇文章中将介绍如何使用 Predis 库所提供的一部分基础但很有用的 Redis 命令。

容易安装

Redis 容易安装,简明的安装说明发表在产品的下载页。从我个人经验来看,如果你运行在 Ubuntu 上而又没有安装 TCL(只需运行 sudo apt-get install tcl 即可安装)将会报错。一旦 Redis 安装完成,你可以运行服务:

Redis 的网站上显示的有很多语言可用的 Redis 客户端,每种语言都有好几个。对于 PHP 来说有 5 个。在本文中我使用的是 Predis 库,但是你可能也需要作为 PHP 模块编译、安装的 phpredis 扩展

译者注:有些人可能在 Predis 库和 phpredis 扩展中难于选择,但两者在一般场景下相差不大,目前都支持 PHP7。phpredis 扩展在性能上可能有一些优势,而 Predis 库源码更加优雅(适合学习、阅读),支持 PHP 新的语法特征,但文档较少(这也是我翻译这篇文章的主要原因)。还有,Predis 也有扩展支持(但作者好像没精力维护了,目前还不支持 PHP7),用于提高性能和提供一下其它的特性。

如果你向我一样在机器上安装的有 Git,你只需克隆 Predis 仓库。否则你就要下载 ZIP 包然后解压。(译者注:可以使用更加简便的 composer 安装:composer require predis/predis

测试一下,创建一个如下内容的 test.php 文件,测试是否能通过 Predis 连接上运行着的 Redis。

当你运行这个脚本,你应该能如愿的看见(输出)信息:”Successfully connected to Redis”。

译者注:这里可能有点小问题,代码不会按照预期捕获 Redis 连接失败的异常,因为在初始化 Redis 客户端类的时候并没有真正的连接,而是在运行第一个命令时才做连接,所以需要额外运行一下 $redis->connect(); 来触发连接操作。详见:https://github.com/nrk/predis/issues/61

使用 Redis

在这个章节你将了解众多 Redis 提供的命令的概况。Memcache 也有相似的命令,如果你熟悉 Memcache,这些列表对你来说看起来都不会陌生。 Continue Reading…

Nginx HTTPS 配置实践

00 前言:

博客使用 HTTPS 已经有一段时间了,最近把当时的配置过程梳理了一遍,希望能对有需要的同学有所帮助。

01 概念介绍:

最近 HTTPS 是越来越流行了,前一阵子的百度,最近的淘宝、知乎,都已经开启了全站 HTTPS 的时代。HTTPS 即 Hypertext Transfer Protocol Secure,简单理解就是在 HTTP 协议上加了一层加密。具体的细节以后弄透彻了再写写。

无利不起早,那么 HTTPS 的好处是什么呢?我个人觉得有以下几点:

  1. 数据传输加密,防止信息被窃取。使用 HTTP 协议时,用户的密码、银行账户、隐私信息等都是在网络上明文传输,很容易被中间人截取。
  2. 防欺诈。当你使用 EV 级别证书(http://www.wosign.com/EVSSL/index.htm)时,浏览器网址显示和一般 SSL 证书不一样。可以对比下:https://www.paypal.com/signin/ 和 https://www.baidu.com/。使用此类证书的网址,主流的浏览器都会在地址栏显示企业的名称(支持中文),增加了网站信任度,进一步防止用户被钓鱼网站欺骗,当然证书的价格也更贵一些。
  3. 防止劫持。这点可以说是国内各大公司下决心支持 HTTPS 的主要原因了。一旦被劫持,用户访问速度会变慢,看到的内容会被篡改,比如商家在百度投放的广告被替换成竞品的广告,淘宝的商品被带上小尾巴(返利链接),甚至直接跳转到x东。这些不光是损害用户的利益,更是直接影响公司收入。
  4. 使用新的技术。比如 SPDY/HTTP2(头部压缩、连接复用、Server Push等) 的基础都是 HTTPS,新协议对移动端 APP 性能提升帮助很大:《双11手淘前端技术: H5性能最佳实践》

当然 HTTPS 不是银弹,不是用了就保险了,安全是一个整体,这是典型的水桶场景,往往一个系统被攻破是在其薄弱的环节。

02 证书申请:

证书申请的大概流程是,首先在自己的服务器使用 openssl 命令(尽量使用高版本的 OpenSSL,除了能规避漏洞,还能使用更高级的密钥加密/交换算法,提升安全性和性能)生成 csr 和 key 文件,命令如下:

如命令参数所示,RSA 的加密强度是 2048 位,使用了更安全的 sha256(SHA-2)哈希算法(SHA-1算法在2016年将不被证书厂商和现代浏览器支持)。

-subj 参数指定证书申请者的信息,如果不直接使用此参数,也会有交互式的命令提示填写这些参数。此部分具体参数释义:

Country Name (2 letter code): 输入国家地区代码,例如中国的 CN

State or Province Name (full name): 地区省份

Locality Name (eg, city): 城市名称

Organization Name (eg, company): 公司名称

Organizational Unit Name (eg, section): 部门名称

Common Name (e.g. server FQDN or YOUR name): 申请证书域名,如果是泛域名证书,则应该填写 *.example.com

Email Address: 电子邮箱

命令还会提示输入challenge password,这个不是加密证书,而是相当于一个二次认证密码,如果厂商证书支持challenge password,而且你也设置了的话,后续证书操作需要验证这个密码,提高安全性。

生成的 CSR(Certificate Signing Request,即证书签名请求)文件包含了证书的主要信息和公钥,同时生成了私钥 key 文件(注意保存)。然后把 CSR 文件提交给 CA 厂商,中间有一个域名所有者验证过程,一般几天后(根据证书类型不同,所需时间不一样)就会发一份邮件给你。

邮件附件一般会带有厂商用私钥签好的证书文件 example_com.crt(注意后缀,内容也变了),同时会给你 CA 的证书链 CA.crt,通常包括 1-2 个中间证书和 1 个根证书,按照证书信任链由下到上,把文件合并(cat COMODOECCDomainValidationSecureServerCA.crt COMODOECCAddTrustCA.crt AddTrustExternalCARoot.crt > CA.crt),统称 CA.crt。也可能没有提供根证书,而且正常来说也不用把根证书放进 CA 证书文件里面,因为浏览器和操作系统都内置了根证书,也只认自己内置的根证书。

03 配置详解:

后面的步骤各个 HTTP Server 就有点不一样了: Continue Reading…

使用七牛云存储加速你的博客

CDN的全称是Content Delivery Network,即内容分发网络。对于它的好处我想大家都知道,但一直以来都只有大公司才用得起。但如今已经有了一些面对中小企业的CDN服务,甚至是免费的。如百度旗下的加速乐(http://jiasule.baidu.com/),安全宝(http://www.anquanbao.com/),而且安全宝还和DNSPod进行了无缝对接,很有吸引力。还有阿里云(http://www.aliyun.com/)开放存储服务 OSS、内容分发网络 CDN。这些都不错,对于个人站长来说质量和价格都能接受。但这些都有一些限制,有些需要备案,有些对个人开发者不是十分友好。

其实对于个人站点来说,只要能加速网站上的静态文件,比如图片、js文件、css文件,网站的访问速度就会大大的提升。像我的网站空间租用的是香港的服务器,ping值基本在45左右,南北互联延迟不是问题,瓶颈在于网页的加载速度(香港的空间一直都是小水管,带宽小)。基于这个需求,七牛云存储(http://www.qiniu.com/)是个不错的选择。每个月有免费的配额,操作又比较简单。它的直接竞争对手又拍云(https://www.upyun.com/index.html)也是个不错的选择。两者都是提供云存储、云处理、云分发的服务。由于七牛云存储后台操作简捷、直接,每个月又有免费的配额,所以个人推荐使用七牛云存储。

说了那么多现在直接进入主题,仅需三部轻松提升博客访问速度。 Continue Reading…

外网免费下载学校图书馆各类论文资源(非原创)

后记:更详细的教程请参考资讯民大的推文【小贴士】置身校外如何安全访问校内资源。同时推荐学弟、学妹们关注资讯民大,了解更多校园资讯以及各种实用功能(查成绩、课表等)。

寒假期间想写论文?该怎么样通过校外网来免费下载学校图书馆的各类资源呢?下面为大家简单的介绍下,学校的系统改进了,现在通过外网(非校园网)同样可以免费下载图书馆的全部资源了。主要使用vpn校外访问系统。

第一步:

使用IE浏览器打开https://vpn.scuec.edu.cn/进入中南民族大学vpn系统。提示访问时可能会看到如下提示,点击“继续浏览此网站”即可,至于为什么会有这个警告请参考http://www.williamlong.info/archives/3461.html

证书警告

第二步登录:

进去后的界面:

vpn登陆界面

右边的其它登陆方式想研究的同学可以看一下,我们直接在左边输入用户名和密码登陆(用户名、密码同教务系统/学生门户的用户名、密码)。 Continue Reading…

win8安装校园网客户端(Edu Supplicant)

是前言的后记(2015-10):下面说的教程Windows 8.1同样适用,Windows 10也可以类似的方法解决。不过这些都已经成为历史了,现在学校早已经是VPN拨号(自带全平台兼容属性)了,插上网线就能自动获得ip,然后使用学号和密码拨号就行。使用路由器就更简单了,现在的“智能”路由器基本都支持VPN拨号,而且和网络中心的老师聊过,学校也没有明面上禁止,因为学校根本就不靠这点网费赚钱(学校钱多就是任性,现在都支持免费申请虚拟机了)。不过风险也有,若是别人用你网做一些“和谐”的事情,因为拨号的学号是你的,到时候“查水表第一个找的就是你(校园网一抓一个准,学校这么好的条件,还是多做点更有意义的事情吧)。

最近有人找我重装系统(好男人,重装系统从不收费),问其原因,她说是win8无法安装校园网客户端。自己装了用不了,网络中心也贴出告示说校园网客户端不兼容win8。她拿到售后去装系统却被告知要收费300(售后真是黑啊,我要是收费30早就发家致富了)。本着不到黄河心不死的精神我决定尝试一下在win8上安装校园网的客户端。在失败N次后得出了正确的安装方法:

在桌面下,右键点击右下角网络图标,打开网络和共享中心。

打开网络和共享中心

点击左侧的更改适配器设置,在弹出的窗口中右键打开以太网(若是外接网卡可能不叫以太网)的属性。

以太网属性

更改ipv4属性。按照学校分配的ip地址进行设置(备用DNS服务器地址填写谷歌的DNS服务地址8.8.8.8能有效解决校园网有时无法打开微博等网页的情况)。

ip地址设置

修改保存后,就会弹出网络中心的一个上网须知,下载64位的操作系统。如未弹出下载页面请自行下载,下载地址:http://172.16.0.2/ATclient64.exe (校园网)备用下载地址:http://yunpan.cn/QpP92ujFyrI68

上网须知

然后需要重启到【禁用驱动程序强制签名】模式下安装校园网客户端。

按win+i键,选择更改电脑设置。

更改电脑设置

点击左侧的常规面板,在右侧最下部选择【立即重启】。 Continue Reading…

windows上安装ruby

其实我不是为了学习ruby而去安装ruby,而是用到有些东西的时候它要使用到ruby的文件组织包gem。就是万恶的gem install。

首先就是要安装ruby,这没什么好说的下载安装就ok了,只是安装的过程中记住选择将ruby添加到系统环境变量中就ok了。下载地址http://rubyinstaller.org/downloads/

现在貌似就安装完了,但其实才刚刚开始而已。

安装后你会发现有时gem install某个程序是还是会报错:“Please update your PATH to include build tools or download the DevKit……”这其实是没有安装DEVELOPMENT KIT的缘故。(参考:http://stackoverflow.com/questions/10694997/gem-install-json-v-1-7-3-gives-please-update-your-path-to-include-build-tools ) 在下载安装ruby的那个网站上下载DEVELOPMENT KIT包,解压,然后cd到解压的目录。依次执行:

提示完成了就OK了。

至此ruby算是安装完成了,然后就可以gem install rails下载rails或者其它需要的程序了。

Y470加装SSD教程以及SSD优化建议

Y470,小Y,2011年的联想性价比较高的游戏影音本,虽然它的下一代y480,y400已经发售。但时至今日(2013.3)还没有停产。i5二代cpu,4G内存,2G的独立显卡,出色之处就在于显存2G的显卡,到目前为止还没有什么带不动的游戏。而它的音响系统也很出色。然而硬盘一直是笔记本的短板(从windows体验指数就能很容易看出),与其无脑的扩充内存还不如换个固态硬盘。

固态硬盘经过2012年的大跌今年开始上涨,不过各种新品频出,各个公司开始加入SSD阵营。(话说内存也涨了很多,12年双十一100块买了一根金士顿4G ddr3内存条,现在涨了几乎一倍价格直逼200)所以有需求的尽快出手吧,不要在等了。 Continue Reading…