让我们尝试编写一个简短的培训,但是相当完整的信息系统,该系统由Go上的服务器部分和Javascript + Vue JS上的客户端Web应用程序组成。
首先,简要介绍一下此应用程序的用途及其用途。 前一段时间,我想到了一个问题,即如何节省我已经结出的一定数量的钱。 甚至对我来说,一个远离金融界的人,也很明显,持有现金是不好的,原因至少有两个:
- 金钱吞噬了通货膨胀(通货膨胀风险)
- 卢布可能贬值(汇率风险)
已决定研究该问题并选择适当的投资工具。 主要标准是可靠性和保护上述风险的储蓄。
我研究了这个问题,得出的结论是,俄罗斯人唯一合适的投资工具是股票交易所交易基金(ETF),以及在莫斯科交易所交易的那些。
因此,我建议编写一个培训应用程序,以显示在莫斯科交易所展示的所有ETF的盈利能力。
您可以说可以在交易所网站本身上查看这种获利能力,并且该应用程序(至少用于培训)应该会有所帮助。 我同意,因此,我们将尝试显示一些有条件的实际库存收益。 所谓有条件的实际回报率,是指根据俄罗斯通胀率调整后的回报率。
在本文的第一部分,我们将分析应用程序的服务器部分。 我们的后端是用Go编写的,在开发过程中,我们将尝试应用这种语言的功能,例如并行代码执行,接口,测试等。
传统知识要求:
- 应要求,应用程序的服务器部分应提供所有Moscow Exchange ETF的报价数据以及每种证券交易所有月的通货膨胀数据。
- 应用程序的服务器部分必须支持多个数据仓库提供程序,在提供程序之间进行切换不应要求更改代码
- 应用程序的服务器部分必须通过http协议提供API,以从存储中接收数据
因此,让我们设计系统服务器部分的软件体系结构。
首先 ,我们将提出应用程序的程序包结构。 根据工作说明,该应用程序将由一个Web服务器组成,该Web服务器将提供REST API并提供该Web应用程序的文件(此后,我们将在Vue上编写SPA)。 此外,根据ToR,我们必须为数据仓库提供者制作几个软件包。
在这一点上,我们应该更详细地介绍。 如何提供在Go中某些功能的提供程序之间切换的功能? 答:使用接口。 因此,我们将需要为包开发一个接口(合同),每个包都将针对其自己的存储类型执行合同。 在本文中,我们将考虑将数据存储在RAM中,但以此类推,您可以轻松添加任何DBMS。 最终的包装结构如下:
其次 ,让我们决定存储接收到的信息的数据类型以及存储提供商的合同。
我们将需要用于股票报价和通货膨胀的数据类型。 我们将按月计算报价和通货膨胀,这种规模非常适合ETF这样的非投机性工具。
该合同将要求使用Mosbirzha服务器中的数据填充存储(初始化)并根据请求提供报价数据的方法。 一切都非常简单。
结果,我们将用于存储报价的类型和接口放在存储模块中:
为简单起见,我们在服务器模块中编写通货膨胀数据:
var inflation = []struct { Year int Values [12]float64 }{ { Year: 2013, Values: [12]float64{0.97, 0.56, 0.34, 0.51, 0.66, 0.42, 0.82, 0.14, 0.21, 0.57, 0.56, 0.51}, }, { Year: 2014, Values: [12]float64{0.59, 0.70, 1.02, 0.90, 0.90, 0.62, 0.49, 0.24, 0.65, 0.82, 1.28, 2.62}, }, { Year: 2015, Values: [12]float64{3.85, 2.22, 1.21, 0.46, 0.35, 0.19, 0.80, 0.35, 0.57, 0.74, 0.75, 0.77}, }, { Year: 2016, Values: [12]float64{0.96, 0.63, 0.46, 0.44, 0.41, 0.36, 0.54, 0.01, 0.17, 0.43, 0.44, 0.40}, }, { Year: 2017, Values: [12]float64{0.62, 0.22, 0.13, 0.33, 0.37, 0.61, 0.07, -0.54, -0.15, 0.20, 0.22, 0.42}, }, { Year: 2018, Values: [12]float64{0.31, 0.21, 0.29, 0.38, 0.38, 0.49, 0.27, 0.01, 0.16, 0.35, 0.50, 0.84}, }, }
第三 ,让我们描述API的端点。 只有两个:报价和通货膨胀。 仅HTTP GET方法。
实际上,从莫斯科交易所网站接收和处理数据是通过初始化方法进行的。 我们根据
交换API的
帮助获取数据。
您应该注意的是:我们被迫对每个安全性使用单独的请求(并且已经有几十个请求了)。 在一个线程中顺序执行数据初始化将花费大量时间。 因此,我们将使用Go的骄傲-goroutines。 请注意以下代码:
在数据初始化功能中,我们将请求并行化到服务器。 实际上,这种站点解析有很多问题:
- 由于怀疑有DoS可能导致自动阻止请求
- 您必须使用上下文模块或控制通道来强制goroutin结束。
- 您需要使用通道从goroutine返回错误
为简单起见,所有这些要点均被省略。
就课程而言,内置的HTTP请求路由器对我们来说足够了。 在更复杂的系统上,您可能希望使用其他一些系统。 就个人而言,我使用的是大猩猩项目中的路由器,但总的来说,它们很多。
随后,我们将添加一个点以上传我们的Web应用程序的文件。 展望未来,我要说的是,您应该只使用返回文件内容。
因此,让我们编写服务器:
我将不在此处提供内存中的存储实现代码,
Github上的所有内容均可用。
要测试我们的API:
通货膨胀引号这样就完成了本文的第一部分。 在第二部分中,我们将为包装编写测试和性能度量。 在第三部分中,我们将开发一个Web应用程序。