学习区块链和小程序开发,用 Go 语言实现抽奖小程序后台

2024-11-19
来源:网络整理

之前在研究区块链,然后看到很多区块链项目都是基于开发的,包括以太坊官方的go-。了解了Go是一个产品后,很多人都说它拥有C/C++的性能,同时也拥有脚本语言的开发效率。我被吸引了并开始了解它。方便后端遇到性能瓶颈以及区块链的发展。

再加上最近小程序的流行,这个技术栈也需要学习和理解。我只是想做一个简单的抽奖小程序。后端可以用Go实现,可以学习小程序开发。一石二鸟,起之。动手实践永远是最好的学习方式。

1.整体背景结构

后端架构

整体后端结构设计如上图:

这样的设计,在彩票这样的场景下,已经可以保证足够的并发和流量了。如果想要增加并发量,可以配置负载均衡进行动态伸缩,然后增加云数据库的处理能力。有时间我会写一下如何进行性能评估以及相应的升级来提高并发。

2、抽奖流程设计

因为我每天工作很忙,没有太多时间。只要准备先研究最简单的彩票逻辑,如果有时间和精力,然后再迭代。用户可以进入小程序创建抽奖活动并设置活动主题、抽奖时间、奖品和数量。然后就可以分享了,其他用户可以点击参与抽奖。到达抽奖时间后,将进行随机抽奖,每位参与抽奖的用户最多只能中奖一次。抽奖结束后,将向所有抽奖用户发送消息提醒。

其实可以简单的用抽签来进行粗略的划分:

一些重要的接口

3.API文档设计

接口文档非常重要,值得认真编写。我认为这是后端开发的基本素质。无论项目大小,良好的文档都是必须的。文档一旦编写完毕,就会带来很多好处。随着时间的推移和迭代,我们仍然可以很好地理解每个接口。接口文档可以将后端开发与外部依赖分离,实现前后端解耦。同时,编写接口文档的过程实际上也是一个思考和梳理的过程。通过详细的讨论和思考,可以明确一些细节,避免一些陷阱。

以下是我维护的文档,从基本描述、域名、基本路径等开始。

然后是每个接口的详细描述,定义了请求和返回结构,以及每个参数的含义和格式。

有关接口的信息

我一般都会在git上维护最新的md格式的接口文档。如果有协作,如果其他人对接口有疑问,不需要每次在沟通中争论,按照文档中的说明调用即可。

4. 实现 4.1 web框架选择

研究了Go的Web框架,最常用的是echo和gin,所以就选一个吧。我选择了echo,感觉文档更完整一点。但与其他语言的Web框架相比,echo的文档太少且不完整,学习和使用的成本较高。

在使用echo的时候,我先把官方文档整体看了一下。最好最全的资料就是官方文档的介绍,所以我要一直坚持学习英语。附网址:

这里的主要流程基本是一样的,注册url处理函数,然后增删改查操作,以及各种内部逻辑。每个请求都带有内部自定义,并在 echo 中进行验证。

4.2 数据库操作 4.2.1

我用的是Go--这个包,地址:

至于如何使用crud,我翻阅了使用文档,地址为:

代码语言:

复制

import "database/sql" import _ "github.com/go-sql-driver/mysql" db, err = sql.Open("mysql", "user:password@tcp(127.0.0.1:3306)/lottery?charset=utf8")

使用()来绑定参数和查询。这里比较麻烦的是获取db中的一行数据,需要Scan()逐一赋值。取出的数据很多的时候有点麻烦,但是我还是喜欢自己控制SQL语句。有些ORM框架使用起来非常简单,但是在编程思维和编写SQL方面没有足够的训练。当你自己写sql时,你会考虑如何优化它。我经常会问自己更多的问题:我可以少执行一次SQL查询吗?查询sql语句能否更加高效?设计的SQL表能不能更好一点?

代码语言:

复制

var (         id int         name string ) rows, err := db.Query("select id, name from users where id = ?", 1) if err != nil {         log.Fatal(err) } defer rows.Close() for rows.Next() {         err := rows.Scan(&id, &name) if err != nil {                 log.Fatal(err) }         log.Println(id, name) } err = rows.Err() if err != nil {         log.Fatal(err) }

代码语言:

复制

_, err = db.Exec("update events set status = ?,cancel_time=? where id = ? and status=?", util.DBEventStatusCANCELED, time.Now().Unix(), queryEvent.ID, util.DBEventStatusINIT)

以上是我用来将抽奖从初始状态设置为取消状态的SQL语句,并使用db.Exec执行更新、删除等语句。

对于交易,可以查看文档了解详情:

代码语言:

复制

tx, err := db.Begin() if err != nil {         log.Fatal(err) } defer tx.Rollback() stmt, err := tx.Prepare("INSERT INTO foo VALUES (?)") if err != nil {         log.Fatal(err) } defer stmt.Close() for i := 0; i < 10; i++ {         _, err = stmt.Exec(i) if err != nil {                 log.Fatal(err) } } err = tx.Commit() if err != nil {         log.Fatal(err) }

4.2.2

每个请求都需要身份验证,这里使用的是身份验证。该库用于操作。

大家的流程都是类似的:连接,然后执行put和get操作。这里有一个简单的封装示例,大家可以学习一下。

4.3 微信登录流程

这里我们可以讲一下微信用户使用小程序的登录流程。

一个。用户进入小程序。小程序使用wx.()登录微信后台。如果登录成功,将获得一个代码。实际返回是这样的:

代码语言:

复制

{errMsg: "login:ok", code: "001nnSQv1QStGa0X1bSv13u7Rv1nnSQA”}

b.小程序将此代码发送到我们自己的后端。

c.后端收到此代码后,拼接一个URL到微信后端,获取微信用户的信息。

代码语言:

复制

https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code

各字段含义:

:此处填写小程序

:小程序

:小程序发送的代码

:授权类型,这里填写即可

我抓起一条日志,查看微信返回的数据。其中,用户对应的会话密钥;、证书的有效时间,单位:秒;、用户的唯一标识。

代码语言:

复制

{"time":"2018-10-13T18:19:41.472758451+08:00","level":"DEBUG","prefix":"echo","file":"auth.go","line":"52","message":"result:map[session_key:ig6tsRoILO2cpxCnk0TXVg== expires_in:7200 openid:(隐私删除)]”}

d.在自己的后台定义登录状态,返回给小程序,即可自定义登录状态。这个时候用户就相当于登录成功了,所以我们给这个用户一个自定义的,然后每次请求都需要携带这个进行验证。

4.4 抽奖活动状态机设计

事实上,整个后端业务逻辑重点是根据彩票的状态进行变化。因此,对于每次启动的彩票,我定义了几个状态。状态机如下:

代码语言:

复制

//数据库中抽奖活动的状态常量, const ( DBEventStatusINIT     = 0 //抽奖中,活动创建后此状态,允许参加抽奖 DBEventStatusOPENING  = 1 //开奖中,不允许抽奖了 DBEventStatusOPEND    = 2 //已经开奖了, DBEventStatusCANCELED = 9 //活动取消 )

抽奖的状态机

5. 总结

完成这件事是相当困难的。我必须学习很多东西并阅读很多文档。比如需要阅读小程序的官方文档,否则后端无法配合登录等。我使用的语言是Go,不是很熟悉。我会一边做一边学习,阅读echo框架的文档。然后设计抽奖的整个流程,设计数据库,设计接口请求和返回格式,编写接口文档。由于大块时间不多,中断后重新连接效率低下。不过,做完整个过程,我感觉自己对Go和小程序有了比较全面的了解。接下来我会继续努力。

那么如何利用它来快速部署呢?如何创建完整的自动化编译、部署、测试流程?以后有时间我会继续总结并发表这些。

分享