您好,欢迎访问三七文档
Erlang实战-构建IP查询服务litaocheng@gmail.comECUGIV2009.10.24目的通过一个具体的开发实例,比较全面的描述erlang项目开发过程。包含的内容:项目目录结构OTPmakefile代码风格edoctype/spec,dialyzereunitcommontestserverrelease1开发任务IP在线查询服务基于HTTP的IP查询服务,用户调用HTTPGET查询某个IP,返回此IP所属的国家,地区等相关的地理信息.项目简洁,高效,具有很好的扩展性.项目地址:获取代码:svncheckout开发任务-IP在线查询服务{cuntroy:China,region:22,city:Beijing,long:116.39,lat:39.93}返回数据为json字符串()GETgeoip?ip=123.8.36.135设计实现开发迅速Erlang开发mochiweb为webserverIP数据库为maxmindGeoLiteCitybinarydbegeoip-GeoLiteCityErlangclientlibrary性能出众采用合适的查询算法Distributed满足性能要求易于扩展逻辑扩展ErlangHotcodeload/swap做好准备?一点WEB开发经验(HTTP,JS总得听过吧)一点基本网络知识(IP不是挨批)一点Erlang知识(至少要在google上搜索过Erlang)“三点”都准备齐了吧!最重要的一点:你对Erlang充满了好奇,看看它是如何完成某些工作!项目目录结构srvErlang源代码(*.erl,*.hrl)ebin编译生成的Erlang目标码(*.beam),.app文件priv项目专有的一些文件,如c代码,专有数据,code:priv_dir/1获取应用的priv目录include包含头文件(.hrl)test测试脚本Note:遵循OTP的目录结构规范,让他人更容易理解你的项目,让Erlang相关工具更好的理解你的项目.erlipsdirectoryOTP是什么在Erlang(FP,并发,message-based)的世界,OO的设计模式不再合适Erlang自己的“设计模式”依照OTP设计出更加规范清晰的application通过对项目的提炼,升华出几种behaviour:gen_server(使用频率极高!80%)gen_fsmgen_eventsupervisorapplication后4种都可以通过gen_server来实现OTPbehaviousgen_servergen_server用来维护某个状态(数据)或提供某项功能(接口)很多逻辑都可以抽象成client/server的结构,gen_server广泛使用gen_server提供通用的server框架,用户模块定义相关callback函数gen_server支持call(sync),cast(asyn),multi_call,abcastgen_server运行在一个独立的process中,复杂的操作会阻塞其他call/cast调用gen_server别搞成死锁:gen_server:handle_call/3中调用gen_server:call/2OTPbehaviousgen_fsmcon't一个有限状态机代码框架在处理clientlifetime,协议交互,server状态等场景下使用在一个独立的process中执行,耗时的操作会阻塞其他调用对于“对象”不同的StateName,需要export相关的Mod:StateName/2,3函数send_event,send_all_state_event为异步调用,sync_send_event,sync_send_all_event为同步调用同gen_server一样,支持start/3,4以独立方式启动gen_fsm,或start_link/3,4以属于supervisortree方式启动OTPbehaviousgen_eventcon't事件处理框架(包括管理器和处理者)在需要对某个事件进行多种处理时,推荐采用gen_event,如Erlang中的error_logger便是采用gen_event,我们可以方便的添加自己的事件处理模块,进行log处理start/0,1,start_link/0,1启动一个事件管理器通过add_handler/3,delete_handler/3,swap_handler/3对事件管理其中的处理着进行操作notify/2为异步调用,sync_notify为同步调用,总是返回ok,call为同步调用,返回对应结果OTPbehavioussupervisorcon't管理gen_server,gen_fsm,gen_event,supervisor或其他processone_for_oneone_for_allrest_for_onesimple_one_for_oneappmon工具查看supervisortreelitao@litaopc:~$erl-bootstart_sasl1appmon:start().%makesuretcl/tk=tcl8.3EmakefileEmakefile为Erlang自带的Make工具,定义如下:%erlipsEmakefile{src/*,[{i,include},{outdir,./ebin}]}.Modules.{Modules,Options}.%Options:参看compilemodule编译(当前路径为Emakefile所在路径):linuxshell:$erl-makeerlangshell:1make:all().GNUMakefileEmakefile不足:Emakefile只能用来编译erl代码缺乏依赖支持无法进行更加复杂的自动化工作使用GNUMakefilemakemakecleanmaketestmakeedoc满足日常所需的各种编译,测试任务。(推荐:GNUautoconf提供一些Erlang相关的Macro,制作更加规范,可移植的生成方法)erlips的MakefileSHELL:=/bin/bash.PHONY:alltestedocdialyzercleanPLT=.dialyzer_pltall:(cdsrc;$(MAKE))test:(cdsrc;$(MAKE)TEST=true)(erl-pa./ebin-evaleunit:test(\./ebin\,[verbose]),init:stop())edoc:(mkdir-p./edoc)(cdsrc;$(MAKE)edoc)plt:(./scripts/gen_plt.sh-asasl)dialyzer:clean(cdsrc;$(MAKE)DEBUG=true)(dialyzer--plt$(PLT)-Werror_handling-Wrace_conditions-Wunderspecs-r.)clean:(cdsrc;$(MAKE)clean)Makefile$makeall#编译erl代码$maketest#调用所有module的eunittest$makeedoc#根据代码中的@doc相关描述,生成edoc$makeplt#调用erlips/scripts/gen_plt.sh生成plt文件:.dialyzer_plt$makedialyzer#根据type,spec信息对代码进行静态分析$makeclean#清理生成的目标码代码erlipsapp.erlapplication,supervisorcallbackmoduleerlips_httpd.erlhttpdmodule,basedonmochiweb_ips_geoip.erlhandlemodulefor/ips/geoip?“requestegeoip.erl解析GeoLiteCitybinaryfile,提供ip查询服务erlips_ctl.erlerlipsctl对应module_demo.erlhandle/demopathErlangModuleTemplate%%%----------------------------------------------------------------------%%%%%%@copyrightyourcompany2009%%%%%%@authorlitaochenglitaocheng@gmail.com%%%@version0.1%%%@docsomedesc%%%%%%-----------------------------------------------------------------------module(mod_demo).-export([some_fun/0]).%%thefunctionsome_fun()-%somecomment...ErlangModuleInVimedoctags@doc书写模块或函数的文档@copyright显示版权信息@doc文档描述信息@version版本信息@spec显示函数的spec信息(目前edoc无法使用-spec)@type显示自定义的type信息@deprecated表示对应信息不推荐使用,将被废除@private私有信息...edoc目前(R13B02-1)对unicode支持不好,还有一些bug如果doc中含有中文会产生错误,许要进行一些修正,参看()edocexamples(src/_ips_geoip.erl)%%%----------------------------------------------------------------------%%%%%%@copyright2009erlips%%%%%%@authorlitaocheng@gmail.com%%%@docthemodulehandletherequestpath:%%%@end%%%%%%----------------------------------------------------------------------%%@dochandlethe/ips/geoiprequest%%@spechandle(Req::any(),Method::atom())-%%{pos_integer(),list(),iodata()}-spechandle(Req::any(),Method::atom())-{pos_integer(),list(),iodata()}.handle(Req,'GET')-.....{200,[],ok}.edocexamples(src/_ips_geoip.erl)typeandspecType预定义类型:any(),none(),pid(),port(),ref(),[],atom(),binary(),float(),fun(),integer(),list(),tuple(),boolean(),char(),string()...自定义类型:-typegender()::'male'|'female'.-typeage()::1..150.-typehttp_code()::pos_integer().-typeheader_list()::[{binary()|string(),binary()|string()}].typeandspecSpec定义type的目的
本文标题:Erlang实战
链接地址:https://www.777doc.com/doc-4614237 .html