mongodb atlas_将您的Go服务与mongodb Atlas连接

mongodb atlas

前言 (Preface)

Many say Golang (or just Go) is a very good choice for developing a service for the cloud infrastructure. And that is mostly true. If you have a stateful service that requires a database in the backend, you may find it difficult to setup such cloud infrastructure and to establish a communication between the Go service and the database server.

许多人说,Golang(或只是Go)是为云基础架构开发服务的绝佳选择。 这基本上是对的。 如果您有一个在后端需要数据库的有状态服务,则可能会发现很难设置这样的云基础架构以及在Go服务和数据库服务器之间建立通信。

Fortunately, there are already solutions that simplify our lives. For example, if you want to store your data in MongoDB, you can use MongoDB Atlas — a fully managed database service in the cloud. We do not explain here, how to setup a MongoDB cluster. It is very well done here. We focus on how to create a connection to MongoDB Atlas with Go and interact with this database cluster.

幸运的是,已经有简化我们生活的解决方案。 例如,如果要将数据存储在MongoDB中,则可以使用MongoDB Atlas( 云中的完全托管数据库服务) 。 我们在这里不解释如何设置MongoDB集群。 这里做得很好。 我们专注于如何使用Go创建与MongoDB Atlas的连接以及如何与该数据库集群进行交互。

先决条件 (Prerequisites)

You need an account on MongoDB Atlas and a running database cluster. The tier M0 Sandbox would be enough, since it is for free use and allows you to store up to 512MB of data. Please make sure your IP is added to the whitelist in your MongoDB Atlas project (see Security -> Network Access). If you deploy the Go service in a Google Kubernetes Engine, you may want to take a look at our next article, which explains how to securely connect a Kubernetes cluster with the MongoDB Atlas.

您需要一个在MongoDB Atlas上的帐户和一个正在运行的数据库集群。 多层M0 Sandbox就足够了,因为它是免费使用的,并允许您存储多达512MB的数据。 请确保您的IP已添加到MongoDB Atlas项目的白名单中(请参阅安全性->网络访问)。 如果您在Google Kubernetes引擎中部署Go服务,则可能需要看一下我们的下一篇文章,其中介绍了如何安全地将Kubernetes集群与MongoDB Atlas连接起来。

创建一个空的Go服务 (Create an empty Go service)

Let us create a simple Go service with two endpoints:

让我们创建一个具有两个端点的简单Go服务:

  • /save to receive a record and to store it

    /save以接收记录并将其存储

  • /read to return the previously stored record back

    /read返回先前存储的记录

The service will listen on port 8080:

该服务将在端口8080上侦听:

import (
"net/http"
)
func main() {
http.HandleFunc("/save", post)
http.HandleFunc("/read", get)
if err := http.ListenAndServe(":8080", nil); err != nil {
panic(err)
}
}
func post(w http.ResponseWriter, req *http.Request) {}
func get(w http.ResponseWriter, req *http.Request) {}

创建与MongoDB Atlas集群的连接 (Create a connection to the MongoDB Atlas cluster)

mgo.v2 is a very useful package for interacting with Mongo and we are going to use it for the MongoDB Atlas as well. Add this function at the beginning of your code:

mgo.v2是与Mongo交互的非常有用的程序包,我们还将在MongoDB Atlas中使用它。 在代码的开头添加以下功能:

func createConnection() (*mgo.Session, error) {
dialInfo := mgo.DialInfo{
Addrs: []string{
"abc-shard-00-00.gcp.mongodb.net:27017",
"abc-shard-00-01.gcp.mongodb.net:27017",
"abc-shard-00-02.gcp.mongodb.net:27017"
},
Username: "MongoUser", // your mongodb user
Password: "YourVerySecurePassword", // ...and mongodb password
} tlsConfig := &tls.Config{}
dialInfo.DialServer = func(addr *mgo.ServerAddr) (net.Conn, error) {
conn, err := tls.Dial("tcp", addr.String(), tlsConfig) // add TLS config
return conn, err
} return mgo.DialWithInfo(&dialInfo)
}

On MongoDB Atlas you always have not just a single database server, but a cluster with several shards. You have to replace the shard addresses abc-shard-00-XX.gcp.mongodb.net:27017 with your own, which you can find here:

在MongoDB Atlas上,您不仅拥有单个数据库服务器,而且拥有多个分片的集群。 您必须用自己的地址替换分片地址abc-shard-00-XX.gcp.mongodb.net:27017

We also added a TLS config into the code, because the MongoDB Atlas denies unencrypted connections.

我们还向代码中添加了TLS配置,因为MongoDB Atlas拒绝了未加密的连接。

Adding the initialization of the session variable completes the first step:

添加会话变量的初始化完成了第一步:

var mongoConn *mgo.Sessionfunc main() {
var err error
mongoConn, err = createConnection()
if err != nil {
panic(err)
} http.HandleFunc("/save", post)
http.HandleFunc("/read", get) if err := http.ListenAndServe(":8080", nil); err != nil {
panic(err)
}
}

使用mongo连接 (Using the mongo connection)

What we have done now is a singleton mongoConn that can be used directly which is not a good idea. Why make it at all? Why cannot we establish a connection every time the client app calls our endpoints?

我们现在要做的是可以直接使用的单例mongoConn ,这不是一个好主意。 为什么要做到呢? 为什么每次客户端应用程序调用端点时我们都无法建立连接?

Because mgo.DialWithInfo(...) can take several seconds before the connection to the MongoDB Atlas is ready. There is a couple of necessary steps like sending and accepting certificates, authorization etc. that needs to be done, before your service can proceed to the next step. You probably want your endpoints to answer within milliseconds, not seconds, right?

因为mgo.DialWithInfo(...)可能需要花费几秒钟的时间才能连接到MongoDB Atlas。 在您的服务可以继续进行下一步之前,需要完成几个必要的步骤,例如发送和接受证书,授权等。 您可能希望端点在几毫秒而不是几秒钟内回答,对吗?

And of course you cannot use the singleton mongoConn in all your endpoints for an obvious reason (due to the side effects by using of a common connection in concurrent HTTP sessions).

当然,由于显而易见的原因,您不能在所有端点中使用单例mongoConn (由于在并发HTTP会话中使用公共连接会产生副作用)。

So, we use a copy of the singleton mongoConn which works quick enough and safe:

因此,我们使用单例mongoConn的副本,该副本足够快速且安全地工作:

session := mongoConn.Copy() // "session" can be used safely
defer session.Close()

Let us implement /save and /read now. We store the data in a sort of generic way: everything what the client app sends us we are going to store in the Mongo database as a byte array.

现在让我们实现/save/read 。 我们以一种通用的方式存储数据:客户端应用程序发送给我们的所有内容,我们都将以字节数组的形式存储在Mongo数据库中。

type MyEntity struct {
Data []byte `json:"data" bson:"data"`
}func post(w http.ResponseWriter, req *http.Request) {
payload, err := ioutil.ReadAll(req.Body)
if err != nil {
panic(err)
} session := mongoConn.Copy()
defer session.Close() entity := MyEntity{Data: payload}
err = session.DB("test").C("data").Insert(entity)
if err != nil {
panic(err)
}
}func get(w http.ResponseWriter, req *http.Request) {
session := mongoConn.Copy()
defer session.Close() entity := MyEntity{}
err := session.DB("test").C("data").Find(bson.M{}).One(&entity)
if err != nil {
panic(err)
} w.Write(entity.Data)
w.Write([]byte{10}) // add a line break for a better look
}

Normally you would not want to panic in case of an error, but return an HTTP error code in the response. However, we want to keep it simple for now.

通常,您不会 因发生错误而 panic ,而是在响应中返回HTTP错误代码。 但是,我们现在想保持简单。

Do not forget to close a copy of your session. MongoDB Atlas considers sessions as a resource and like every other database server has a limit for the amount of opened connections.

不要忘记关闭会话副本。 MongoDB Atlas将会话视为资源,并且像其他所有数据库服务器一样,对打开的连接数量也有限制。

We are ready to test our endpoints!

我们准备测试我们的端点!

测试端点 (Testing the endpoints)

You can start the service with following command:

您可以使用以下命令启动该服务:

> go run main.go .

If it worked, you will be able to save your data into the MongoDB Atlas cluster with curl:

如果可行,您将能够使用curl将数据保存到MongoDB Atlas集群中:

> curl -i -XPOST http://127.0.0.1:8080/save --data 'Here is my record'HTTP/1.1 200 OK
Date: Fri, 10 Jul 2020 13:03:03 GMT
Content-Length: 0

…and fetch this data again via /read

…并通过/read再次获取此数据

> curl -i -XGET http://127.0.0.1:8080/readHTTP/1.1 200 OK
Date: Fri, 10 Jul 2020 13:06:24 GMT
Content-Length: 18
Content-Type: text/plain; charset=utf-8Here is my record

At least, it worked for us.

至少,它对我们有用。

If you want to download the entire source code of this topic, visit us at github.com/setlog/go-mongo-atlas

如果要下载此主题的完整源代码,请访问我们的网站github.com/setlog/go-mongo-atlas

Be nosy and stay connected!

多管闲事,保持联系!

Image for post

翻译自: https://medium.com/swlh/connect-your-go-service-with-mongodb-atlas-1ec6da2b9b88

mongodb atlas

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值