0

我已经将一个端点从我们的 PHP 7 应用程序换成了一个新的 Go 服务。该服务采用地理边界框并从 mongo 数据库返回属性。问题是它目前花费的时间是旧 PHP 服务执行相同操作的时间的 4-5 倍。大约 90% 的时间花在下面的 GetProps 函数上。

var session *mgo.Session

func connectToDB() *mgo.Session {
    dialInfo := &mgo.DialInfo{
        Addrs:    []string{"xxx1.mongodb.net:27017", "xxx2.mongodb.net:27017", "xxx3.mongodb.net:27017"},
        Database: "admin",
        Username: "me",
        Password: "xxx",
        DialServer: func(addr *mgo.ServerAddr) (net.Conn, error) {
            return tls.Dial("tcp", addr.String(), &tls.Config{})
        },
        Timeout: time.Second * 10,
    }
    session, err := mgo.DialWithInfo(dialInfo)
    if err != nil {
        log.Panic(err)
    }
    session.SetMode(mgo.Monotonic, true)
    return session
}

func GetProps(propRequest Request) []Property {
    results := make([]Property, 0)
    sessionCopy := session.Copy()
    defer sessionCopy.Close()
    props := sessionCopy.DB("mapov").C("properties")
    props.Find(bson.M{
        "geo": bson.M{
            "$geoWithin": bson.M{
                "$geometry": bson.M{
                    "type":        "Polygon",
                    "coordinates": propRequest.BoundingPoly,
                },
            },
        },
    }).Sort("-rank").Limit(propRequest.CpPropsRequired).All(&results)
    return results
}

func init() {
    session = connectToDB()
}

PHP 7 服务的功能几乎相同——

$collection = $mapovdb->properties; 
$query = ['geo' => [
  '$geoWithin' => [
    '$geometry' => [
      'type' => 'Polygon',
      'coordinates' => $boundingPoly
    ]
  ]
]];

$cursor = $collection->find( $query, $queryOptions); // $queryOptions includes the matching sort and limit 

但这要快得多(我将这两个服务并排运行了 12 个小时,使流量随机化)。

我尝试更改我的属性结构,所以它只需要一个字段,但这似乎并没有影响性能。

type Property struct {
    Name         string    `bson:"name" json:"name"`
}

我究竟做错了什么?当然我应该能够匹配 php7 驱动程序的性能?

更新

我已经将内置 http 库换成了fasthttp。这似乎使一切变得更快。我还没有时间弄清楚为什么(但当我这样做时会回到这里)。我目前的理论是,内置的 http 库为每个新的 tcp 连接而不是每个新的 http 连接创建一个新的 goroutine,这导致我的 db 查询排队 - 要么是因为负载均衡器正在重用 tcp 连接,要么是因为客户端正在重用它们(http/2?)。

4

0 回答 0