百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

Elixir实战:11 组件工作 (4) 配置应用程序

myzbx 2025-01-21 20:01 33 浏览

一个 OTP 应用程序可以使用称为应用环境的功能进行配置——一个键值的内存存储,其中键是原子,值是 Elixir 术语。您可以通过配置脚本文件提供应用环境值——位于配置文件夹中的 Elixir 脚本。

mix 工具确保在应用程序启动之前,配置已加载到应用程序环境中。最后,您可以使用 Application 模块中的函数检索环境值。

11.4.1 应用环境

让我们看一个简单的例子。待办事项 HTTP 服务器当前监听一个硬编码的端口:5454。在这个例子中,您将通过操作系统环境变量使 HTTP 端口可配置。

设置应用程序环境的最典型方法是使用 config/runtime.exs 文件。这是一个在运行时评估的脚本,正好在应用程序启动之前。在这里,您可以设置应用程序的环境配置以及其任何依赖项。

要使 HTTP 端口可配置,您可以从操作系统环境变量中读取配置并将其存储到应用程序环境中。

清单 11.14 配置 HTTP 端口 (todo_env/config/runtime.exs)

Bash
import Config                                           
 
http_port = System.get_env("TODO_HTTP_PORT", "5454")    
config :todo, http_port: String.to_integer(http_port)   

导入配置助手

读取操作系统环境变量

设置应用程序的环境值

在这里,您使用 System.get_env/2 读取操作系统环境变量 TODO_HTTP_PORT ,如果该变量未设置,则使用默认值 5454 。然后,您使用导入的 Config.config/2 函数来配置 :http_port 设置的 :todo 应用程序。

一旦您启动系统,此设置在应用环境中可用,您可以检索它——例如,使用 Application.fetch_env!/2 函数:

Bash
$ iex -S mix
 
iex(1)> Application.fetch_env!(:todo, :http_port)
5454

在系统启动之前设置操作系统环境变量会影响应用程序环境:

$ TODO_HTTP_PORT=1337 iex -S mix
 
iex(1)> Application.fetch_env!(:todo, :http_port)
1337

现在,您可以调整 Todo.Web 的代码以从应用程序环境中读取端口。

列表 11.15 获取 http_port 设置 (todo_env/lib/todo/web.ex)

defmodule Todo.Web do
  ...
 
  def child_spec(_arg) do
    Plug.Cowboy.child_spec(
      scheme: :http,
      options: [port: Application.fetch_env!(:todo, :http_port)],   
      plug: __MODULE__
    )
  end
 
  ...
end

从 :todo 应用环境中检索 HTTP 端口

在这种情况下,您使用 Application.fetch_env!/2 ,如果未配置 HTTP 端口,将会引发错误。要提供一个默认值(如果未设置),您可以使用 Application .get_env/3 (https://hexdocs.pm/elixir/Application.xhtml#get_env/3)。

11.4.2 变化配置

在某些情况下,您可能希望在不同的 Mix 环境中使用不同的设置。例如,您当前在开发和测试中始终使用相同的 HTTP 端口。因此,如果待办事项系统在开发中启动,您将无法运行测试。解决此问题的方法是在测试 Mix 环境中使用不同的 HTTP 端口。

注意 值得注意的是,环境一词被过度使用。应用环境是一个键值存储,保存您 OTP 应用程序的各种设置。Mix 环境确定编译目标,例如开发、测试或生产。最后,操作系统环境由当前 shell 会话中存在的操作系统级变量组成。

要在不同的 Mix 环境中更改设置,您需要对 config/runtime.exs 进行一些更改。

列表 11.16 混合环境特定设置 (todo_env/config/runtime.exs)

import Config
 
http_port =
  if config_env() != :test,                              
    do: System.get_env("TODO_HTTP_PORT", "5454"),        
    else: System.get_env("TODO_TEST_HTTP_PORT", "5455")  
 
config :todo, http_port: String.to_integer(http_port)

基于混合环境做出决策

在这里,您依赖导入的 Config.config_env/0 来确定用于构建项目的 Mix 环境。然后,在测试环境中,您将使用不同的操作系统环境变量和不同的默认 HTTP 端口。应用环境名称始终相同( :http_port ),因此其余代码无需更改。

让我们快速验证一下这是否有效。在默认开发环境中启动应用程序:

$ iex -S mix
 
iex(1)> Application.fetch_env!(:todo, :http_port)
5454

现在,在测试环境中尝试相同的操作:

$ MIX_ENV=test iex -S mix
 
iex(1)> Application.fetch_env!(:todo, :http_port)
5455

此时,即使系统在另一个操作系统进程中启动,您也可以运行测试。

还有一个额外的不便之处。数据库文件夹目前始终是相同的,无论混合环境如何。因此,运行测试将污染您当前的开发数据。

为了避免这种情况,您可以使数据库文件夹可配置,使用不同的操作系统环境变量和测试环境中的不同默认值,就像您对 HTTP 端口所做的那样。为了简洁起见,这里不提供代码,但建议您自己尝试或查看 todo_env 文件夹中的实现。

11.4.3 配置脚本注意事项

值得一提的是,Elixir 还支持构建时配置脚本。如果您创建 config/config.exs 文件,该脚本将在项目编译之前进行评估。因此,您从外部源(例如操作系统环境)读取的任何设置都是在构建机器上完成的。

如果您在与运行系统的机器不同的机器上构建系统(这是一种良好的实践),系统可能会最终配置不正确。由于这种微妙的混淆,以及由于其特殊的语义(它在编译时被评估),尽量少使用 config.exs。在大多数情况下,runtime.exs 应该满足您所有的需求。

如果您正在开发一个库,请尽量避免通过应用程序环境传递参数。如果一个库通过应用程序环境接受参数,那么其用户就被迫通过配置脚本提供这些值。一个更灵活的方法是设计库的 API,使其接受所有参数作为函数参数。采用这种方法,库的用户在决定如何提供参数时拥有完全的自由。他们可以硬编码参数,通过应用程序环境配置参数,或者在运行时从外部源获取参数。有关更多详细信息,请参阅官方文档中的“库指南”页面(https://hexdocs.pm/elixir/library-guidelines.xhtml#avoid-application-configuration)。

摘要

  • OTP 应用程序是一个可重用的组件。该应用程序可以运行整个监督树或仅提供实用模块(如在库应用程序中)。
  • 非库应用程序是一个必须启动监督树的回调模块。
  • 应用程序允许您指定对其他应用程序的运行时依赖关系。这与编译时依赖关系不同,后者允许您从项目中获取外部代码并进行编译。
  • 应用环境允许您提供应用程序设置。如果您想向系统操作员公开一些配置,这可能会很有用。

相关推荐

路痴的福音 谷歌地图AR实景导航Live View正式上线

2月份起,谷歌地图开始测试一项新功能,即是在行人导航功能中加入AR实景导航。用户可以通过设备屏幕,在实际的街道中见到路线指示,使导航功能不只在地图上,而是更融合在真实环境中。谷歌地图AR实景导航(图源...

Google地图怎么设置中文 谷歌地图app设置语言为中文

Google地图是一款知名的地图导航客户端,这是一款很好用的地图软件,Google地图怎么设置中文呢,不少人可能不是很清楚,下面就和小编一起来看看吧!Google地图怎么设置中文方法1、点击打开谷歌地...

谷歌地图说这里能过

来源:日本沙雕日常谷歌地图说这里能过#微博新鲜事#

谷歌地图已可离线导航 仅安卓机可用

谷歌已经在今年的谷歌IO大会上确认了地图离线导航功能,如今该功能已经可以在安卓机上使用了。这对网络资源较为贫瘠且相对昂贵的国家来说可谓提供了便利。用户需要提前下载所需旅程的部分地图,虽然不能获得实时路...

谷歌地图测试速度更快的AR实时视图

上个月谷歌为了庆祝谷歌地图成立15周年,为谷歌地图推出了新的图标,并且重新设计了移动应用程序。谷歌还预览了一些即将推出的功能,现在正在测试地图导航之外更快的实时视图(LiveView)访问。谷歌之...

谷歌地图新功能 离线地图可导航和搜索

【中关村在线软件资讯】5月29日消息:在今天凌晨召开的GoogleI/O开发者大会上,谷歌公布了一些关于地图的新功能。谷歌地图离线模式新版谷歌地图有更好用的离线地图,可以在无网络的情况下搜索地点、查...

谷歌地图变这样,谁还花钱去旅游?

足不出户,在手机上能身临其境的游览世界各地。文章来源:创下一个新ID:cxygx1作者:创新君编辑:卝生话说在前天的GoogleI/O2022开发人员活动中,谷歌推出了一种全新的地图模式,可以...

新版谷歌地图将添新功能:知道你想去哪儿

据外媒TheVerge报道,谷歌即将为安卓版谷歌地图增加一些新的功能,从而使之变得更加智能,比如可以推算出用户的目的地等。新版谷歌地图将添新功能(图片来自TheVerge)报道称,升级后的谷歌地图将会...

谷歌地图安卓版获效率改进,11.136.x更新引入“表单风格”卡片

IT之家7月16日消息,谷歌在今年2月宣布将对自家地图应用进行大修,目前相关更新已经实装入谷歌地图11.136.x版本中,主要围绕UI进行效率改进。谷歌提到,现在用户在查找地址时,...

谷歌地图安卓/iOS版界面大修,超漂亮

IT之家(www.ithome.com):谷歌地图安卓/iOS版界面大修,超漂亮IT之家报道,Android5.0已经正式到来,谷歌旗下的应用为了迎接安卓5.0都采用了全新的MaterialDes...

谷歌地图在美国启用“美国湾”称呼

参考消息网2月11日报道据法新社2月11日报道,美国总统特朗普10日对谷歌地图将墨西哥湾更名为“美国湾”表示欢迎,这符合他在1月底重返白宫后签署的法令之一。这一占超主导地位的地图服务现在为位于美国的用...

外交部回应谷歌地图涉南海标注:南海一直是国际社会公认通用地名,被广泛接受

【环球时报-环球网报道记者李萌】在4月15日外交部例行记者会上,有记者提问称,据报道,谷歌地图显示了“西菲律宾海”的名称,此前这里显示的是南海。有人称这有助于保护菲律宾的主权,请问中方对此有何评论?...

谷歌地图首曝数据:覆盖全球98%居住区,已拍千万英里街景

12月13日,谷歌透露了其街景车(StreetViewcar)等设备为绘制世界地图所做的工作。目前,谷歌已经捕获了超过1000万英里的街景图像,这个距离相当于绕地球400圈。旗下航空地图服务谷歌地...

美媒:谷歌称,当联邦地图作出更改时,谷歌地图将使用“迪纳利峰”及“墨西哥湾”新名称

来源:环球网【环球网报道】据美国全国广播公司(NBC)等媒体报道,美国谷歌公司27日称,当联邦地图作出更改时,谷歌地图将使用“迪纳利峰”和“墨西哥湾”的新名称,即“麦金利山”和“美国湾”。本月20日...

谷歌地图迎来15周年重大更新 界面重新设计 新增贴心功能

昨日,恰逢谷歌地图15周年生日,谷歌地图便迎来重大更新。不仅仅界面重新设计,还添加了许多贴心功能。名为“TransitAttributes”的新功能会根据过去用户共享的详细信息,向人们提供有关公共场...