易栈网-膘叔

浏览模式: 标准 | 列表 | 图文
思路的变迁:go  memcachep

思路的变迁:go memcachep

前言

最近在项目中写了一个小型 的socket服务器,于是就需要PHPclient来向他发送和接收数据,但是这时带来的问题,如果php每次创建socket连接1是开销比较大,2是连接远程性能可能也不佳,于是进行了曲线过国的过程,在本地用go写了一个server,php只向本地发送数据,由本地的server长连接到socket服务器,这样开销就会小很多(之所以这样,是因为socket服务器需要登录验证,PHP如果为了发个包,每次都登录验证消耗太大)
过程
在用go写server的过程中,遇到了这种问题,原来用C写的server,我们担心C server接受数据慢或者担心并发不够,于是php在发送数据的时候,用的是shm_系列函数,但发现shm系列函数不太稳定,正常使用使用就会溢出。于是转成了msg_xxx系列函数,并调整了系统参数,使得发送和接收的最大队列提高了很多
但是go lang对msg_xxx支持的不好,首先他没有自带,其次在调用RawSyscall的时候(参考了hover给的c函数中的参数,结果是go可以msg_send,但不能msg_receive,总说参数长度不对),最后,其实我是不想用cgo啦。
最后我参考了“囧囧孙”的网站(www.jiongsun.com/2012/12/38.html),实现了一个udp server。当然在这之前,我已经实现了一个http server的方案,不过我觉得本地udp server的话应该会更快。
其实,我觉得本地如果操作同一个管道文件,应该会更方便更快,毕竟,只是php写go读(但因为对系统的底层了解不多,也没有找到相应过多的资料,就暂时放弃了。比如,我看到了php://fd/1之类的,但没有实际例子也没有过多的在那里看。怕浪费太多的时间 )
转变
其实转变就在昨天,asta的群里,有个名为“囧”的朋友发布了一个网站(https://github.com/xiaojiong/memcachep),并说明他的go server是按照memcache的协议标准来实现的,也就是说,PHP只需要使用new memcache('server','port'),连接上server,然后get/set就OK了。这让我突然之间豁然开朗。
是啊,我在远程服务器实现了socket server,那个socket server是为其他平台服务,我PHP连接是比较麻烦,但如果我专门现实了一个GET/SET的接口,PHP发送过去不就OK了?也不用PHP写socket_create之类的函数,也不需要php来担心一些其他可能发生的问题。甚至如果以后socket server有多台了,我这里也可以利用memcache的addServer来实现多台发送?(当然也要socket server实现)。性能?可能是会略有降低,但难道,本地一个go server/php udp连接就一定高吗?开的服务越多,环节越长,出错的概率就会越高,如果我只是单点直接向socket server发送数据,这样出错还是有据可查的
准备
昨天就开始准备重写原来的socket server了。
socket server上面要做的事情比较多:
1、转发PHP发来的各种消息
2、转发失败后需要发送apns通知
3、在发通知前,需要查询数据库中每个用户ID的token,并更新多少未读信息
之前的server只做了纯转发功能。准备再花上一段时间把它搞定。
supervisor 守护程序

supervisor 守护程序

最近听到supervisor的机会越来越多了,主要是因为越来越喜欢将程序放到底层去运行,但又需要守护程序来监控它,万一它挂了怎么办?如果为每个程序都写上这样的脚本,那得写多少啊?

结果,在最近的看到的网上的内容里,就看到一大堆人在说用supervisor吧。

1、Asta谢的《build-web-application-with-golang》:第12章:应用部署

2、还是Asta谢的beego框架:Supervisord

3、来自the5fire的:进程管理器supervisor的使用(django实例)

其实还有很多关于这样的内容,就不一一贴出来了。只是beego框架中的介绍会相对比较简单,所以可以拿来当教程,再加上我的程序可能也会趋向于使用go来开发,就转贴一下这篇博客吧,只有三步:

  1. 安装 setuptools

    wget http://pypi.python.org/packages/2.7/s/setuptools/setuptools-0.6c11-py2.7.egg   sh setuptools-0.6c11-py2.7.egg    easy_install supervisor   echo_supervisord_conf >/etc/supervisord.conf   mkdir /etc/supervisord.conf.d 
  2. 修改配置 /etc/supervisord.conf

    [include] files = /etc/supervisord.conf.d/*.conf 
  3. 新建管理的应用

    cd /etc/supervisord.conf.d vim beepkg.conf 

    配置文件:

    [program:beepkg] directory = /opt/app/beepkg command = /opt/app/beepkg/beepkg autostart = true startsecs = 5 user = root redirect_stderr = true stdout_logfile = /var/log/supervisord/beepkg.log
安装St2的Dash插件

安装St2的Dash插件

st2目前应该是快超越Editplus成为广大开发人员手中必备的编辑器了吧?在写go的时候,我也用上了它,而且也用了gosublime来做为辅助,虽然,无闻说只要按cmd+.,cmd+h,就可以进行跳转查看变量等,但我有dash,可以看任何语言,我该怎么配置?

其实官方有现成的例子,在这里,你也可以看到英文版:https://sublime.wbond.net/packages/DashDoc,我稍微中文化一下吧

1、打开st2的菜单:preferences -> package control -> install package,搜索dashdoc进行安装,安装完成后就可以使用了(dashdoc功能只支持mac)

2、将光标移到需要查询的变量的英文上,按ctrl+h,即会自动打开dash,跳转到指定函数(测试了一下,只要你文件名的后缀正确,你在dash里又安装了相应的文档包,dash还是可以直接认出来的)非常方便

以下是小小的例子,打开一个golang的程序,将光标移到函数名上:

按下ctrl+h,

OK,我们还想看这个函数的源码,点击右边的函数名(该功能是看具体文档来实现的,目前go的文档是可以这样看源码的,PHP的不行,其他的未知)

有没有感觉到,高端大气上档次?想知道dash还支持些啥 ,其实APP内部已经告诉你了:

其实appcode是用idea的核心的,所以appcode的plugin能够在idea系的软件上安装,比如phpstorm,安装后也就可以跳转了,具体按哪个快捷键,我就不告诉你了,自己安装一下就知道了

PhpStorm 7 EAP 131.61

PhpStorm 7 EAP 131.61

看到标题不要以为我是来介绍新品的,其实我是来吐槽的。

看changelog里,这里改进了很多,但居然有一个功能坏掉了。这个功能。。。。是我天天要用,几乎时时要用的功能。难道phpstorm的用户已到了纯OO时代?不再需要写else了??
else后面的大括号居然不再自动完成了。而且默认输入else的时候就是一个错误的红色(红色可能与我的配色有关)。实在让人受不了。
虽然这次有一些feture还算不错。

From the PHP side, this build delivers:

  • Scope highlighting for PHP control structures – alternative syntax (WI-566)
  • Type inference fixes (e.g. @return static[] now works as it should, WI-13242)
  • Symfony Console standalone for Laravel and Doctrine (WI-18196)
  • PHPUnit on Server fixes
  • Traits-related inspections are introduced (class can’t extend trait, interface can’t extend traits)
  • and more bug fixes and improvements…
但毕竟else认错也太不科学了。这应该算是一个低级bug了吧?

网站挂了半天

其实从昨天晚上11点多开始就挂了。VPS提供商对我说,他们遭受攻击了。他们旗下的几台服务器,全部被攻击,导致无法正常使用。已经联系了美国机房那边

有时候想想,技术何苦为难技术,MD,都是吃这碗饭的人,何苦呢。
所幸,中午的时候,恢复了。总算没有达到24小时。和VPS提供商扯了扯皮,继续使用。
突然间,我想起我一年前想的,多站互为镜像 之类的想法,然后写个脚本,用来监控,一旦发现有问题了,立刻调用dnspod的接口,更新数据信息
不过,人有点懒了,想找个人一起做做事。
linux 批量重命名文件

linux 批量重命名文件

其实说白了就是利用sed,但怎么个用法,确实是有点想法,毕竟sed的功能实在太强了。

单一文件重命名就太简单了,mv一下就全来了。批量怎么办?
OK,一句话:
for i in `ls`; do mv -f $i `echo $i | sed 's/????/?????/'`; done
看到没。其实就是一个for in,然后 mv 一下。只是mv的蚨,用sed进行了改名,用上了管道,echo 等。
接着来:
1、改文件的首字母为a:
for i in `ls`; do mv -f $i `echo $i | sed 's/^./a/'`; done
2、改文件的末字母为a
for i in `ls`; do mv -f $i `echo $i | sed 's/.$/a/'`; done
3、文件名加前缀:
for i in `ls`; do mv -f $i `echo "prefix_"$i`; done
4、文件名小写变大写
for i in `ls`; do mv -f $i `echo $i | tr a-z A-Z`; done
顾名思议,大写变小写就是将A-Z和a-z换一个位置
5、改指定字符为其他(如后缀名)
for i in `ls`; do mv -f $i `echo $i | sed 's/.html/.php/'`; done
更多技巧,请参考sed的用法
php能做什么?

php能做什么?

最近好象关于PHP能做什么的话题又出来了。其实说白了,PHP啥都能做,进可攻退可守。有人说,PHP没有多线程,没有这没有那。其实很多人都用PHP实现了这些功能。

先说其他的,上次thinkinlamp聚会的时候,一位台湾朋友就展示了php用来做类似单片机功能的事情。也从侧面证明了,PHP可以搞类似驱动的事情(也只能在linux下面,毕竟linux下面任何东西都是文件)
PHP还能做什么?有人用php来自己做Web服务器。或许有人说了,PHP自带不是有PHP -S xxx:81吗?其实是很多人用socket自己实现了webserver。
还有人说PHP没有多线程,但PHP在linux下面fork进程后,也能算是当成多线程了吧。
只是目前可能是异步在实现上没有那么好吧。
有些项目大家可以看看的,先不谈有人直接用C实现PHP的框架,这没意思,为了提升性能,这些代码我们都看不到了。
不过,有些纯用PHP实现的玩意可以学习一下。这些代码,也不错,思路更不错
1、reactphp
2、aopphp
3、国内的swolephp
这些都是改变思路的程序,如果你要学多进程,其实,你可以看APNSPHP,即能用来当成apns server,你也可以照着学多进程的程序。
转:如何封杀尝试Raspberry Pi SSH密码的来源IP

转:如何封杀尝试Raspberry Pi SSH密码的来源IP

标题是标题,但其实讲的内容当然是不一定只是在树梅的设备上用的。不要太纠结于表面,我不改标题是为了尊重原作者

原文来自于hugo zhu的网站:http://hugozhu.myalert.info/2013/03/08/block_failed_ssh_attempts_with_iptable.html,看了他的名字,你也可以猜出他的微博定就是http://weibo.com/hugozhu。OK,不扯蛋,上原文:

Raspberry Pi整天开着,如果用缺省SSH端口对外开放,就会经常遇到扫描SSH密码的肉鸡。虽然密码不是很简单,但还是感觉很不安全的。

系统的ssh登录日志文件在:/var/log/auth.log,登录失败时会记录以下格式的日志:

  1. Mar 7 10:31:51 raspberrypi sshd[24510]: Failed password for root from 221.8.19.129 port 4066 ssh2
  2. Mar 7 10:31:55 raspberrypi sshd[24514]: Failed password for root from 221.8.19.129 port 4079 ssh2
  3. Mar 7 10:31:56 raspberrypi sshd[24518]: Failed password for sshd from 221.8.19.129 port 4080 ssh2
  4. Mar 7 10:32:26 raspberrypi sshd[24522]: Failed password for sshd from 221.8.19.129 port 4149 ssh2

用最简单的Shell脚本来解决这个问题:

guard.sh

  1. #!/bin/bash
  2. last_ip=""
  3. tail -f /var/log/auth | while read LINE; do
  4. {
  5. if [[ "${LINE}" =~ "Failed" ]]; then
  6. ip="$(echo ${LINE} | awk '{print $(NF-3)}')"
  7. if [[ "$last_ip" == "$ip" ]]; then
  8. echo "block $ip"
  9. #curl -s --data-ascii "uuid=<my iphone's uuid>" --data "body=${LINE}" http://raspberrypi/pushme
  10. iptables -A INPUT -s "$ip" -j DROP
  11. fi
  12. last_ip=$ip
  13. echo $LINE
  14. fi
  15. }
  16. done

用root用户执行以下命令,也可以放到启动脚本里:/etc/rc.local

  1. nohup /root/bin/guard.sh > /var/logs/guard.log 2>&1 &

如果连续两次输错密码,那ip就会被封,我另外加了一个报警,会通知到我的手机,这下感觉安全了些。

登录Pi用iptables -L可以看到被封杀的IP列表,如果需要解封这些IP,可以用命令iptables -F,也可以用crontjob每天定时运行一次iptables -F来清除

脚本还很简单,还可以有不少改进,可以在评论里讨论。

---EOF---

越来越发现,sablog需要改版了。再不改。alexa排名下降不说,最关键的是,代码的显示不爽了。只是想到改版后有几千篇的文字需要一一调整就痛苦。

getPageRank for golang

getPageRank for golang

不多说了。其实这是一个复刻版,原来的PHP代码就在注释里面。在google play上面已经存了代码了。如果你觉得我这里的代码看起来不方便,可以移步play.golang.org。

package main

import (
"fmt"
"io/ioutil"
"net/http"
"net/url"
"strings"
"unicode/utf8"
)

/**
//https://github.com/phurix/pagerank/blob/master/pagerank2.php
function GetPageRank($q,$host='toolbarqueries.google.com',$context=NULL) {
$seed = "Mining PageRank is AGAINST GOOGLE'S TERMS OF SERVICE. Yes, I'm talking to you, scammer.";
$result = 0x01020345;
$len = strlen($q);
for ($i=0; $i<$len; $i++) {
$result ^= ord($seed{$i%strlen($seed)}) ^ ord($q{$i});
$result = (($result >> 23) & 0x1ff) | $result << 9;
}
if (PHP_INT_MAX != 2147483647) { $result = -(~($result & 0xFFFFFFFF) + 1); }
$ch=sprintf('8%x', $result);
$url='http://%s/tbr?client=navclient-auto&ch=%s&features=Rank&q=info:%s';
$url=sprintf($url,$host,$ch,$q);
@$pr=file_get_contents($url,false,$context);
return $pr?substr(strrchr($pr, ':'), 1):false;
}
*/

func main() {
fmt.Println(getPageRank("http://neaststudio.com"))
}

func getPageRank(urlstring string) string {
seed := []byte("Mining PageRank is AGAINST GOOGLE'S TERMS OF SERVICE. Yes, I'm talking to you, scammer.")
seedlen := len(seed)
result := 0x01020345
q := []byte(urlstring)
qlen := len(q)
for i := 0; i < qlen; i++ {
seedmod := i % seedlen
seed_ascii, _ := utf8.DecodeLastRuneInString(string(seed[seedmod]))
q_ascii, _ := utf8.DecodeLastRuneInString(string(q[i]))
result ^= int(seed_ascii ^ q_ascii)
result = ((result >> 23) & 0x1ff) | result<<9
}
result = -(^(result & 0xffffffff) + 1)
ch := fmt.Sprintf("8%x", result)
u, _ := url.Parse("http://toolbarqueries.google.com/tbr")
uq := u.Query()
uq.Set("client", "navclient-auto")
uq.Set("ch", ch)
uq.Set("features", "Rank")
uq.Set("q", "info:"+string(q))
u.RawQuery = uq.Encode()
resp, err := http.Get(u.String())
if nil != err {
return err.Error()
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if nil != err {
return err.Error()
}
//pagerank只有一位,所以可以直接取最后一位。。。免去正则
if len(body) <= 0 {
return "error"
}
pagerankbody := strings.TrimSpace(string(body[:]))
return pagerankbody[len(pagerankbody)-1:]
}

play.golang的地址是:http://play.golang.org/p/uACC-1rdF3

不过,在网页上执行会报错的,说是没有权限。。本地测试成功
转:macbook air/pro外接显示器的显示模式及设置

转:macbook air/pro外接显示器的显示模式及设置

在转贴之前,我来说说我现在的事儿。2年前买了个转接口,moshi的,一直用的都很正常,初期是在macmini上用的,一点问题都没有,后来自己也在101上用过。没啥问题。现在给我颜色看了,只能认得出显示器型号,但显示器上一直显示:无信号接入。。。,换了几个机器和几个显示器都这样,看来就是接口坏了吧?

真郁闷。

OK,再来转贴吧。。。原文地址在:http://bbs.weiphone.com/read-htm-tid-1984643.html

最近发现有部分朋友都在问外接显示器的相关问题,但是似乎没有太多的介绍,就我自己的体会简单说说,说错的话希望指出,不太会编辑,大家见谅!。

这里说的外部显示器既包括显示器又包括投影、电视等。

macbook外接显示器显示方式据我所知有四种情况:

1、合盖模式
就是只使用外接显示器显示,笔记本显示器不显示同时可以合上盖使用。显示性能上来看,这种显示模式是最大化利用显卡,显卡可以专注于外在显示器,所以显示效果是最好的,同时显示器不工作,对合盖后的散热又一定帮助,是外接显示器最普遍的应用。

2、镜像模式
就是笔记本显示器和外接显示器都同时显示同一个完整画面,笔记本合盖则进入睡眠状态。显示性能上来看,这种显示模式需要显卡分配资源在两个显示器上同时显示,所以显示效果是最差的,一般运用在交流、讲课、会议上对显示效果没有太大要求的场所。

3、扩展模式
就是同一个画面分别扩展到两个以上显示器上显示,可以实现每个显示器显示同一个画面的不同部分,笔记本合盖则进入睡眠状态,这种显示模式同样需要显卡在多个显示器上分配资源,但是又比镜像模式资源消耗小,所以显示效果一般,一般运用在多屏同时使用多个程序工作的场所,由于mac程序分离化的特点,这种模式在mac下运用也比较广泛。

4、混合模式
就是镜像模式和扩展模式混合使用的情况,要有3台以上显示器支持(包括笔记本自带的显示器),这种模式可以在两台或更多显示器上扩展显示一个画面,而另外一个(或多个)显示器镜像扩展的那个画面,这种模式对显卡消耗是最高的,效果也不是特别理想,一般应用在特殊的复杂场合。

四个模式设置问题:

首选看看几个模式的优选顺序,无任何设置时,外接显示器即为扩展模式,如果勾选镜像模式的话,镜像模式的优先权最高(也就是说勾选镜像模式的话,很有可能不会进入合盖模式和扩展模式),在扩展模式下,进行设置拖移,则进入混合模式。

1、合盖模式设置
这个模式下必须保证外接电源,不然有可能不会被唤醒。首先连接电源,然后连接显示器,接下来分两部分,如果是有线鼠标键盘,则合上盖直接点击鼠标键盘直接唤醒;如果是蓝牙鼠标键盘,则在蓝牙设置里设置能被该设备唤醒(蓝牙设置--选择设备--高级--勾选选项)然后合盖,点击该设备唤醒。在合盖模式时不能勾选镜像模式。
合盖模式退出,进入合盖模式后,拔去外部显示器连线或者在显示器设置里选择镜像模式就退出合盖模式,但是如果显示器不是苹果的或者不能确定是否支持热插拔的话,最好先点击睡眠,在睡眠状态拔出连接线。

2、镜像模式设置
这个模式很简单,连接外部显示器,在显示器选项中设置两个或以上显示器的分辨率(最好设置成相同的,不过一般系统会自动设置)然后点“排列”,勾选“镜像显示器”就可以。
退出镜像模式,把“镜像显示器”的勾去除就可以,注意,在镜像模式不能进入合盖模式和扩展模式。

3、扩展模式设置
这个模式是默认的,连接外部显示器,没有勾选镜像模式,没有被合盖唤醒进入合盖模式,那就是扩展模式。在扩展模式下,点击“排列”,然后根据说明进行相应的排列就可以。
退出扩张模式,只要进入合盖模式或者勾选“镜像显示器”就退出扩展模式。注意,可能需要在笔记本显示器上对扩展操作进行设置。

4、混合模式设置
将三台或以上显示器设置为扩展模式,然后按住option键把一个显示器图标拖移到准备镜像的显示器上,以镜像这两个显示器(镜像更多的也按照这个方法进行)松开option,把其他的拖移成扩展。

其他一些设置:
1、在镜像与扩展模式中快速切换可以按F7键实现。(能否退出合盖模式没有尝试过,望有心人指正)
2、有时候电脑不能自动识别显示器,则按照先连显示器再连电脑的顺序试一遍(平常也最好以这个顺序进行连接)
3、外接显示器的时候,有可能出现显示器上显示效果不理想的问题,特别是字体,首先尽量使用合盖模式,其次在外观显示里勾选使用LCD平滑字体,最后在字体大小哪里选择适合的值,这个不是必然的过程,也就是说只要在那一步解决了就没有必要再去下一步设置。

另外说一下mac的字体显示,说通俗点,win下是优先显示器显示效果,锐化优化了字体的很多显示效果,mac下是优先纸张显示效果,没有刻意的对字体进行优化和锐化,所以,在win下字体看上去更清晰更饱满,但是打印出来就不一定是这个效果,而mac下看起来可能会发虚可能锐化不够,但是显示效果是什么打印出来纸张上的效果就是什么,这就是很多设计者喜欢在mac上设计的原因,也是win和mac看上去有区别的原因,所以,以上的方法再怎么调,显示效果也不可能和win一致。
主要是这篇写的非常详细,如果需要图文类型的,网上也有很多文章,我就不一一转载了。