离家将近一周了,我爸也没有打电话向我诉说无法上网之类的。网站也没看到完全无法启动。目前比较满意了。考虑到网络的现实情况,一切基本正常,当然,翻墙希望也是正常的。改天将路由器的相关配置贴出来,备份一下。这篇文章由手机发出。不知道出来的样子是怎样的。我还是习惯 emacs的html 的方式
月度归档: 2013年3月
erlang NIF的一些想法及杂念
昨天回了一趟上海,其中有家公司使用erlang做服务器,感兴趣就看了看,
大概聊了聊。这几个月一直在看关于C#的内容,都没有看过或者写过
erlang的代码了,感觉生疏了好多。
大约去年11月份的时候吧,我头一次注意到erlang的NIF,其实,我当
时是在找JNI相关的一些资料,然后就大概看了一下NIF的流程,结构,写
了一些代码做测试使用。之后就再也没有碰过了。
昨天聊的时候,想到了mysql的过程存储,感觉如果erlang来弄的话,
会更方便,如果结合NIF的话,在存储的过程中,即实现了逻辑,也简化了
存储的操作步骤,而且还很高效,对我而言,更感兴趣的是接口的封装提
供了很大的便利性,想一想在做架构的时候可以少些很多代码,确实很不
错,要知道我最讨厌的是审代码,每次一碰到这种事情总看的我想吐。
但这里对于我而言,如果使用服务器的话,觉得有一些问题,主要是想
满足下面的场景:
在NIF的执行过程中,需要调用erlang实现的另外一个函数,或者向另
外的erlang进程发送消息,执行完成后,接着执行NIF的代码,然后返回到
erlang的调用环境中。
比如说在网游的战斗中,当使用过程存储的方法时,在erlang的查询函
数中,修改玩家自身的属性是一个(比如在NIF中计算结果,并返回结果),可能还需要同时调用别的玩家的一些
功能函数(在NIF中调用别的erlang函数运算),如果复杂的话,NIF计算,
并将一部分数据发送给需要的玩家进程,或者仅仅调用函数,总的做完之
后,再将需要的数据存储,调用mnesia:tran….什么的(我记不住函数,
基本上都是写了一个之后编辑器自动补充的)
我知道erlang中可以通过drive的方式或者port的方式来实现调用,
erl_interface在单独的进程中也可以调用某个节点的函数或者给进程发送
消息,相关的例子代码显示这样子是可以的,我并没有去验证(官方给的
例子似乎也不用验证吧),但不知道是否可以在NIF中使用。
如果可以在NIF中使用的话最好了,不知道erl_interface有没有调用本
地节点的函数,如果没有的话,就只好使用调用远程节点的函数了,不知
道效率会不会降低太多。如果效率降低太多的话,大不了将函数都修改为
进程,大家一些消息来消息去的。
明天又要出去一趟了,没有时间去验证想法了。等回到上海了再验证吧,
最近自己似乎都在跑来跑去的,在电脑前都呆不了多长时间。不过,考虑
下乡下的网络条件和时不时的来下停电之类的,就很头疼。网络时不时的
抽风下,网站也时不时的抽风下,如果不幸停电的话,至于来电的时候网
站是不是会自动启动就不敢肯定了,不过从前几次来看,运气还算不错,
都可以恢复,不过挂在路由器上的2T硬盘(做NFS使用)就比较惨了,来电的时候自检太
长时间,导致第一次不会自动挂载,需要重启路由才行。等下个月回到上
海就会稳定多了。
过段时间考虑买两个Pi,来做家里的服务器,现在路由器兼职的内容太
多了,每次看到剩余只有2MB内存可用就担心一些功能出现问题(虽然有交
换内存,但还是担心)
程序代码模块热替换
这是一篇几年前就想写的一篇文章,初始于最初学习Erlang的时候。初
步的研究是在研究Java的ClassLoader机制。
但这也是一篇没有经过严格验证的文章,由于操作系统实现的复杂性,
没有经过完整的确认。
因此,下面的内容仅是理论的推定。
程序代码的热替换非常的麻烦,真实的环境需要考虑比如代码正在执行
中,需要进行热替换,这会丢失非常多的信息而难以进行。因此,这里做
了一些的约定(其实,Erlang要实现代码的热替换也相同的有一些限定)。
- 代码中的不使用全局变量或者静态变量
- 被替换的代码只有在不运行的时候才允许被替换
这一约定用来简化程序代码热替换时实现的复杂量。这样可以将程序使
用的所有的数据和代码独立出来,当进行代码替换时,保证数据还是原来
的数据。至于对数据内容或者格式的更新,在替换的代码中实现。这一步
限定了使用dll的方式,至于实现的机制架构,BREW系统就是一个可行性的
例子。
这一约定会将热替换的使用稍微复杂些,但简化了实现机制,Erlang的
代码的热替换也是这样的约定。这样一来,对于线程之类的,当线程在运
行的时候,需要等线程结束才可以进行代码的替换,对于使用者而言,需
要在监测到模块代码文件更新的时候重启线程的调用,甚至保存部分的结
果之类的。因此,在调用的时候需要约定要相应机制的接口。
在满足上述的两个条件下,大致的实现如下:
主程序做最简单的事情,在监测线程中不断的监测模块文件的时间戳信息。
当监测到时间信息不一致的时候,准备进行模块的热替换。如果模块没有
加载,则加载模块,并调用约定要的初始化函数,初始化函数将会将模块
分配的数据保存在主程序中。如果模块已经被加载,则首先卸载掉模块
(在卸载函数中,由模块自己通知其他的卸载调用,并告之卸载缘由),
由于约定1的存在,数据依然是保留的,然后加载新的模块,并调用更新数
据的函数(更新数据函数通知其他部分自己的更新)。如果模块已经卸载,
则重新加载。主程序退出的时候,卸载所有的模块(在卸载函数中,由模块自己通知其他的卸载调用,并告之卸载缘由)
在上述的流程中,一个非常关键的内容是接口约定时的顺序以及参数,上述实现
大概约定的公用接口为4-6个不等,但在模块内部分管理自己的接口的时候,
需要对自己的函数表做一个非常严格的维护,在代码进行替换前,需要和
其他模块,尤其是依赖模块进行沟通,不然的话会危及整个系统的稳定性。
理论上而言,dll加载到内存中的时候,磁盘上的文件是可以进行替换
的,但这个操作要看操作系统了,比如windows默认就不可以,会提示说文
件正在被使用,也有可能会出现由于这个dll被多次加载而无法完成正确的
替换调用。而对于我自己在嵌入式中做的动态加载机制,大都没有实现的如此
复杂,上述的机制是可以实现的。
所以,还是Erlang使用的方便,不用再重新造轮子了。。。
openwrt vpn自动分流翻墙
将openwrt的相关配置记录下来,防止下次找不到。理论上而言,vpn连接上之
后的设置都是通用的。我用的是支持pptp的vpn。
opkg update
opkg install ppp-mod-pptp kmod-pptp kmod-mpe kmod-gre
vi /etc/config/network
config interface 'tun0'
option ifname 'pptp-vpn'
option proto 'pptp'
option server 'x.x.x.x'
option username 'xxxx'
option password 'xxxx'
option peerdns '0'
option metric '2000'
config route
option interface 'tun0'
option target '1.2.3.4'
option gateway '10.3.4.1'
config route
option interface 'tun0'
option target '2.3.0.0'
option netmask '255.255.0.0'
option gateway '10.3.4.1'
第一段是添加一个名字为tun0的网络接口,拨号协议时pptp。peerdns为0表示
使用默认的dns服务器,不是用vpn获取到的dns服务器。由于我只是指定固定的ip
通过vpn访问,所以就这样配置了。
第二段和第三段是指定通过vpn的网络规则,分别对应单独的一个IP和一个范
围的IP.
vi /etc/ppp/option.pptp
#mppe required,no40,no56,stateless
由器中检查流量的走向的时候,将会是正确的,但局域网中的电脑却还是默认的路
径。
iptables -I FORWARD -o br-lan -j ACCEPT #允许br-lan端口流量被转发
iptables -I FORWARD -o tun0 -j ACCEPT #允许tun0端口流量被转发
iptables -t nat -I POSTROUTING -o tun0 -j MASQUERADE #tun0出口的流量SNAT出去
检查可以了,就这么用着了。
vi /etc/config/firewall
config zone
option forward 'ACCEPT'
option output 'ACCEPT'
option name 'vpn'
option network 'tun0'
option masq '1'
option mtu_fix '1'
option input 'REJECT'
config forwarding
option dest 'vpn'
option src 'lan'
以上大部分都可以通过web页面设置,只是通过shell的话我觉得更清楚些,也
懒得截图额。
如果vpn服务器是国外的话,那么恭喜咯,局域网中的电脑可以自动按照规则翻
墙了,当然,你也可以用来做电信和网通的加速使用。
PS: 相同的文章写两遍就是痛苦啊,明明昨天写了一次,结果在emacs中不小心
按了将alt将ctrl键用了,弄的找也找不回来。不熟悉的键盘配置就是麻烦啊。
android 4.2.2调试关于adb连接的问题
<
adb在android 4.2.2中连接时需要确认开发的电脑的RSA KEY在手机的白名单中,但奇怪的是,我的无论如何在手机测都没有那个RSA KEY的确认对话框。
没办法,只好手动来操作了。其实也很简单,只需要将电脑的~/.android/adbkey.pub复制为手机的/data/misc/adb/adb_keys就可以了。注意,adb_keys是个文件名,不是目录,所以在复制的时候注意重命名。
这下终于可以调试了。好无奈啊。