现在游戏需要你做一个物品强化的功能,不说逻辑的问题,这个时候我们一定会想到一个问题,那就是在功能已经实现的情况下,这些数据从哪得到,三种情况1数据库 2ets表 3配置文件!
1数据库 那么如果是存储在数据库里,结果就是我们每次进行一个简单的强化操作,我们读一次数据库,这样是完全不可取的,因为太影响速度先不管数据量是否大,检索算法有多快,并发数量有多高的问题,光是中间的调度问题就不可小觑,小一点的游戏数据库和系统在同一个服务器上可能还好一些,如果是在不同的服务器上就废废了,如果再赶上玩家多,并发量大,对数据库的操作特别多那就更慢了!但是即便不可取我们也还是要考虑一下是否这样有优点,当我们手动更改了配置文件的时候,配置数据的更新就是实时的,也就是说我们不用停止服务器,数据就可以更新上去!
2配置文件 那么如果是直接使用配置文件呢?这个时候我们都是打开一个输入输出流来操作,erlang里提供了一个file模块专门来处理这类问题,还是强化装备,这个时候要获取数据,那么我们打开了一个文件拿到数据进行操作,你可能感觉这样会更快一些,其实不然,文件其实就是硬盘存储的方式,小数据量的文件确实没有什么影响,但是如果是同时多人强化,读取配置文件,那就真的是麻烦到家了!
3ets表
前两种都不行,那我们怎么办,这时候要考虑的是内存存储了,erlang里一提到内存存储我们首先想到的就是ets,而且可以保证进程间共享内存,使用他来操作再不合适不过了,无论是配置表还是数据库读出来的数据我们都可以加载到内存里,然后直接去读取内存,这种方式很高效,解决了我们的需求
先看一下file模块的加载方法
consult(Filename) -> {ok, Terms} | {error, Reason} %%Filename要包含路径切记
那么我们来做一个简单的读取配置文件并加载的小程序!!!先做一个简单的配置文件streng.config
{a, 11,22}.
{b, 11,22}.
{c, 11,22}.
{d, 11,22}.
{e, 11,22}.
{f, 11,22}.
-module(streng)
-export([load/1]).
-define(?STRENG_FILE, "../streng.config").
load() ->
{ok, Data} = file:consult(STRENG_FILE),
case ets:info(?MODULE) of
undefined ->
ets:new(?MODULE, [set, public, named_table,{read_concurrency, true}]);
_Other ->
ok
end,
lists:foreach(fun(SingleData) ->
case Key of
{} ->
none;
_ ->
true = ets:insert(?MODULE, Key)
end
end, Data),
ok.
这样我们就写了一个简单的像ets里加载配置文件的方法,值得注意的是,ets加载的位置是你调用方法的进程内存里,这样的加载方式是直根据你的配置表的主键向ets里加载,如果你想要根据得到这些数据也是要根据主键去查找的(这里使用第一个字母列为主键)
下面是查找我们存到ets里的数据
get_data(Key) ->
Result = ets:lookup(?MODULE, Key),
case Result of
[] ->
{};
[Data] ->
Data
end.
get_Second(Data) ->
erlang:element(2, Data). %%你可以看看文档,这个方法是做什么用的,虽然现在你可能已经明白了
get_Third(Data) ->
erlang:element(3, Data).
这里我们完整的完成了我们的工作,这只是简单的操作,这样做并不美观,也不便于理解,更重要的是,这么做很不直观,配置文件的内容也没有显示出来,当有一天一个新的程序猿来修改你的代码的时候,他很难从你的代码里了解你的配置文件内容,还有一点就是ets存储的也只是很普通的一组组数据如果有必要去看ets的话,我们也完全不了解我们存的是什么,当一个进程存储了大量的配置文件信息的时候,依靠这种方式,我们很难通过UI去了解到底这个进程里存了那些东西,借此我们利用record重新写一下这个方法!
-module(streng)
-export([load/1]).
-define(?STRENG_FILE, "../streng.config").‘
-record(streng,{
id,
num,
count
}).%%这个record只是我随便定义的名称
load() ->
{ok, Data} = file:consult(STRENG_FILE),
case ets:info(?MODULE) of
undefined ->
ets:new(?MODULE, [set, public, named_table,{read_concurrency, true}]);
_Other ->
ok
end,
%%重点在这里,加载一个将数据封装与record里加载到ets中
lists:foreach(fun(SingleData) ->
{Id, Num, Count} = SingleData,%%匹配单条数据到你的变量里
StrengSingleData = #streng{
id = Id,
num = Num,
count = Count
},
true = ets:insert(?MODULE, {Id, StrengSingleData })%%这里以id为主键插入相应的数据
end, Data),
ok.
这样看是不是感觉更为直观,如果你在record后面加上相应的注释,你的整个加载方法就能体现出配置文件的内容了,便于后期他人的查阅和维护,那么我们在来看以下这种方法的时候取数据应该怎么做
get_data(Key) ->
Result = ets:lookup(?MODULE, Key),
case Result of
[] ->
{};
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[Data] ->
Data %%我们可以换一种取法,因为这时这样直接取Data已经没有太多的意义了,我们可以直接返回总的数据而不要主键信息(如下)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[{Id, Info}] ->
Info
end.
get_Second(Info) ->
Info#streng.num.
get_Third(Data) ->
Info#streng.count.
这样的一个简单的配置文件加载到ets的读取操作就算完成了,举一反三,如果是数据库的操作我们也可以按照这个方法,不管你是用的是Menisa还是其他的数据库,都可以依照这个方式来加载到ets,只不过是改变一下数据读取方式,方法是相通的唯一不同的是数据的来源。
那么我们如果修改了配置文件怎么办,而我现在又不想关掉服务器重新加载?那么就可以单独写一个模块,去调用loading()方法,我们在控制台也好,或者依靠其他方式也罢,直接调用即可,那么ets就会被重写,很多公司也会根据自己的需求去写一个类似的动态加载脚本,这里我们就不多说了
当然,到了最后还是要顺带说一句,我们一般的情况下都是在启动节点的时候就将这类的配置文件加载到相应的进程里了(你可以参想一下,gen_server或者superviours的init()回调函数,我们在init里来处理加载问题),在每一个节点会有一个单独的进程专门存储这类配置文件,由于我们设置的ets格式是可以在进程间共享的,所以这类公共资源文件就很容易被各种方法调用,很是方便!
分享到:
相关推荐
**RabbitMQ 默认配置文件模板详解** RabbitMQ是一款开源的消息队列系统,基于AMQP(Advanced Message Queuing Protocol)协议实现,广泛应用于分布式系统中,用于解耦应用程序,提高系统的可扩展性和容错性。在...
readers可以在Emacs的配置文件中添加以下内容,以启用Erlang mode: (setq load-path (cons "<Erlang OTP 安装路径>/lib/tools-<版本号>/emacs" load-path)) (setq erlang-root-dir "<Erlang OTP 安装路径>") ...
在Erlang编程环境中,模块级别的热部署是一项关键特性,它允许开发者在不中断系统运行的情况下更新或替换已加载的模块。这对于实时系统和高可用性服务尤其重要,因为它们需要持续提供服务而不能因为代码更新而停机。...
首先,需要下载最新版本的 Emacs for Windows 并解压缩,然后建立 .emacs 配置文件。在 .emacs 文件中,添加以下配置以启用 Erlang 模式: (setq load-path (cons "C:/progra~1/erl5.8.2/lib/tools-2.6.6.2/emacs" ...
5. **集成到项目**:将编译好的Erlang MySQL库添加到你的项目中,通常将其放置在`ebin`目录下,然后在你的应用配置文件中引用它。这样,你的Erlang程序就能使用这个库来执行SQL查询和管理数据库。 现在,让我们深入...
- **配置加载**:`loadConfig(FileName)`用于加载指定配置文件中的信息。 通过以上封装和优化,Erlang的进程字典不仅能够有效实现Memcache服务,还能够灵活适应不断变化的业务需求,确保系统的高效运行和数据的可靠...
- **解析**: 使用Erlang内置库或第三方库进行CSV文件的读取和解析。 - **应用场景**: 数据导入导出。 #### 39. Erlang文件操作 - **文件读取**: 使用`file:read_file/1`函数读取文件内容。 - **注意事项**: 需要...
`optc.tar.gz`可能是一个Erlang应用的释放包,包含了多个版本的源码和相关的配置文件。而`otp_code_change_avi.rar`可能是讲解Erlang OTP(Open Telecom Platform)中代码变化的视频教程,OTP是Erlang的标准库,提供...
2. **Application的配置**:每个Application都有一个`.app`文件,位于`ebin`目录下,例如`bank1.app`。这个文件定义了应用的名字、版本、依赖的其他应用以及模块列表。基本格式如下: ```erlang {application, ...
Erlang 23引入了一些新特性,例如改进的错误处理、新的模块加载机制和对Unicode的更好支持。RabbitMQ 3.8.17则可能包含了一些安全修复、性能提升和功能增强。 在实际部署中,确保Erlang版本与RabbitMQ版本兼容至关...
确保遵循Erlang的模块命名规范,并在`rabbit.app`配置文件中声明你的模块。 在测试和调试过程中,可以使用Erlang的调试工具如`dbg`或`recon`。这些工具可以帮助你跟踪进程、查看内存使用情况和监控系统状态。 最后...
安装完成后,将Distel的源代码克隆或下载到你的`~/.emacs.d`目录下,然后在你的`.emacs`配置文件中添加与Windows类似的相关设置。 3. **启动Emacs**:启动Emacs,检查Distel是否正确加载,如果一切正常,你就可以...
- 配置`$ERL_LIB`路径,以便自动加载Mochiweb。 2. **获取依赖**: - 通过SVN检出Mochiweb。 - 获取GeoIP数据库并解压。 - 获取egeoip客户端库。 3. **编写代码**: - 实现`gen_server`行为的各个回调函数。 - ...
3. **配置Erlang SDK**: 安装Erlide后,需要配置Erlang的SDK路径。这通常包括erts和lib目录,它们包含了Erlang的运行时系统和标准库。在Eclipse中,选择"Window" -> "Preferences" -> "Erlang" -> "Installations",...
2. **创建释放包**:使用`rebar3`或`escript`等工具,将编译后的beam文件、应用配置文件和应用描述文件(.app)打包成一个可部署的释放包(通常是一个.tar.gz文件)。 3. **部署到节点**:将释放包复制到目标Erlang...
应用章节则阐述了如何定义和组织应用,包括应用的概念、回调模块、资源文件、目录结构、应用控制器、加载和卸载、启动和停止、配置和应用启动类型。 分布式应用章节讨论了如何定义和指定分布式应用,以及如何处理...
总结,这个压缩包提供了在Linux环境下运行RabbitMQ所需的一切,包括Erlang运行时和RabbitMQ服务器本身,以及基本的配置文件。通过正确配置和使用这些资源,你可以在你的系统上搭建一个功能齐全的消息中间件平台,...
如果你有自定义的Erlang模块或者第三方应用,将其路径添加到`ERL_LIBS`可以确保它们在运行时被正确加载。 脚本化安装不仅方便,还便于在多台服务器上快速部署Erlang环境,尤其在运维场景中非常实用。例如,通过结合...
3. **配置管理**:XML格式的配置文件可以被`erlsom` 解析,转换为Erlang术语,便于程序读取和操作。 4. **XML文档处理**:任何需要解析或操作XML文档的场景,`erlsom` 都能提供高效和便捷的解决方案。 总之,`...
应用(Application)在Erlang/OTP中是一个封装了代码、模块、资源文件和配置文件的实体,它可以被加载和卸载。应用的设计目的是为了封装功能相关的代码,便于管理和维护。每个应用都具有自己的启动和停止过程,以及...