Heim Backend-Entwicklung Golang Einführung in die Funktionsweise von Golang mit Redis, MySQL und RabbitMQ

Einführung in die Funktionsweise von Golang mit Redis, MySQL und RabbitMQ

Nov 25, 2019 pm 03:59 PM
golang

Einführung in die Funktionsweise von Golang mit Redis, MySQL und RabbitMQ

golangOperation Redis&Mysql&RabbitMQ:

Reids

Install import

go get github.com/garyburd/redigo/redis
import "github.com/garyburd/redigo/redis"
Nach dem Login kopieren

Use

Verbinden

import "github.com/garyburd/redigo/redis"

func main() {
    c, err := redis.Dial("tcp", "localhost:6379")
    if err != nil {
        fmt.Println("conn redis failed, err:", err)
        return
    }
    defer c.Close()
}
Nach dem Login kopieren

set & get

       _, err = c.Do("Set", "name", "nick")
    if err != nil {
        fmt.Println(err)
        return
    }

    r, err := redis.String(c.Do("Get", "name"))
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(r)
Nach dem Login kopieren

mset & mget

Batch set

      _, err = c.Do("MSet", "name", "nick", "age", "18")
    if err != nil {
        fmt.Println("MSet error: ", err)
        return
    }

    r2, err := redis.Strings(c.Do("MGet", "name", "age"))
    if err != nil {
        fmt.Println("MGet error: ", err)
        return
    }
    fmt.Println(r2)
Nach dem Login kopieren

hset & hget

Hash-Operation

   _, err = c.Do("HSet", "names", "nick", "suoning")
    if err != nil {
        fmt.Println("hset error: ", err)
        return
    }

    r, err = redis.String(c.Do("HGet", "names", "nick"))
    if err != nil {
        fmt.Println("hget error: ", err)
        return
    }
    fmt.Println(r)
Nach dem Login kopieren

expire

Ablaufzeit festlegen

   _, err = c.Do("expire", "names", 5)
    if err != nil {
        fmt.Println("expire error: ", err)
        return
    }
Nach dem Login kopieren

lpush & lpop & llen

Queue

 // 队列
    _, err = c.Do("lpush", "Queue", "nick", "dawn", 9)
    if err != nil {
        fmt.Println("lpush error: ", err)
        return
    }
    for {
        r, err = redis.String(c.Do("lpop", "Queue"))
        if err != nil {
            fmt.Println("lpop error: ", err)
            break
        }
        fmt.Println(r)
    }
    r3, err := redis.Int(c.Do("llen", "Queue"))
    if err != nil {
        fmt.Println("llen error: ", err)
        return
    }
Nach dem Login kopieren

Verbindungspool

Each Die Erklärung der Parameter lautet wie folgt:

MaxIdle: Die maximale Anzahl inaktiver Verbindungen. Dies bedeutet, dass auch ohne Redis-Verbindung N inaktive Verbindungen aufrechterhalten werden können, ohne gelöscht zu werden und sich im Standby-Zustand zu befinden jederzeit.

MaxActive: Die maximale Anzahl aktiver Verbindungen, was darauf hinweist, dass höchstens N Verbindungen gleichzeitig vorhanden sind

IdleTimeout: Die maximale Wartezeit für inaktive Verbindungen. Nach dieser Zeit wird die inaktive Verbindung unterbrochen geschlossen sein

  pool := &redis.Pool{
        MaxIdle:     16,
        MaxActive:   1024,
        IdleTimeout: 300,
        Dial: func() (redis.Conn, error) {
            return redis.Dial("tcp", "localhost:6379")
        },
    }
Nach dem Login kopieren

Beispiel für einen Verbindungspool:

package main

import (
    "fmt"

    "github.com/garyburd/redigo/redis"
)

var pool *redis.Pool

func init() {
    pool = &redis.Pool{
        MaxIdle:     16,
        MaxActive:   1024,
        IdleTimeout: 300,
        Dial: func() (redis.Conn, error) {
            return redis.Dial("tcp", "localhost:6379")
        },
    }
}

func main() {
    c := pool.Get()
    defer c.Close()

    _, err := c.Do("Set", "name", "nick")
    if err != nil {
        fmt.Println(err)
        return
    }

    r, err := redis.String(c.Do("Get", "name"))
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(r)
}
Nach dem Login kopieren

Pipeline-Betrieb

Der Anfrage-/Antwortdienst kann eine kontinuierliche Verarbeitung neuer Anfragen implementieren. Der Client kann mehrere Befehle an den Server senden Ohne auf eine Antwort zu warten, können Sie schließlich mehrere Antworten in einem lesen.

Verwenden Sie die Methoden Send(), Flush() und Receive(), um Pipeline-Vorgänge zu unterstützen.

Send schreibt Befehle in den verbundenen Ausgabepuffer.

Flush löscht den Ausgabepuffer der Verbindung und schreibt ihn auf den Server.

Recevie liest die Antwort des Servers nacheinander in FIFO-Reihenfolge.

func main() {
    c, err := redis.Dial("tcp", "localhost:6379")
    if err != nil {
        fmt.Println("conn redis failed, err:", err)
        return
    }
    defer c.Close()

    c.Send("SET", "name1", "sss1")
    c.Send("SET", "name2", "sss2")

    c.Flush()

    v, err := c.Receive()
    fmt.Printf("v:%v,err:%v\n", v, err)
    v, err = c.Receive()
    fmt.Printf("v:%v,err:%v\n", v, err)

    v, err = c.Receive()    // 夯住,一直等待
    fmt.Printf("v:%v,err:%v\n", v, err)
}
Nach dem Login kopieren

Mysql

Import installieren

go get "github.com/go-sql-driver/mysql"
go get "github.com/jmoiron/sqlx"

import (
    _ "github.com/go-sql-driver/mysql"
    "github.com/jmoiron/sqlx"
)
Nach dem Login kopieren

Verbinden

import (
    _ "github.com/go-sql-driver/mysql"
    "github.com/jmoiron/sqlx"
)

var Db *sqlx.DB

func init() {

    database, err := sqlx.Open("mysql", "root:@tcp(127.0.0.1:3306)/test")
    if err != nil {
        fmt.Println("open mysql failed,", err)
        return
    }

    Db = database
}
Nach dem Login kopieren

Tabelle erstellen

CREATE TABLE `person` (
  `user_id` int(128) DEFAULT NULL,
  `username` varchar(255) DEFAULT NULL,
  `sex` varchar(16) DEFAULT NULL,
  `email` varchar(128) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
Nach dem Login kopieren

(einfügen)

package main

import (
    "fmt"

    _ "github.com/go-sql-driver/mysql"
    "github.com/jmoiron/sqlx"
)

type Person struct {
    UserId   int    `db:"user_id"`
    Username string `db:"username"`
    Sex      string `db:"sex"`
    Email    string `db:"email"`
}

var Db *sqlx.DB

func init() {
    database, err := sqlx.Open("mysql", "root:@tcp(127.0.0.1:3306)/test")
    if err != nil {
        fmt.Println("open mysql failed,", err)
        return
    }
    Db = database
}

func main() {
    r, err := Db.Exec("insert into person(username, sex, email)values(?, ?, ?)", "suoning", "man", "suoning@net263.com")
    if err != nil {
        fmt.Println("exec failed, ", err)
        return
    }
    id, err := r.LastInsertId()
    if err != nil {
        fmt.Println("exec failed, ", err)
        return
    }

    fmt.Println("insert succ:", id)
}
Nach dem Login kopieren

(Aktualisieren)

package main

import (
    "fmt"

    _ "github.com/go-sql-driver/mysql"
    "github.com/jmoiron/sqlx"
)

type Person struct {
    UserId   int    `db:"user_id"`
    Username string `db:"username"`
    Sex      string `db:"sex"`
    Email    string `db:"email"`
}

var Db *sqlx.DB

func init() {

    database, err := sqlx.Open("mysql", "root:@tcp(127.0.0.1:3306)/test")
    if err != nil {
        fmt.Println("open mysql failed,", err)
        return
    }

    Db = database
}

func main() {

    _, err := Db.Exec("update person set user_id=? where username=?", 20170808, "suoning")
    if err != nil {
        fmt.Println("exec failed, ", err)
        return
    }

}
Nach dem Login kopieren

(auswählen)

package main

import (
    "fmt"

    _ "github.com/go-sql-driver/mysql"
    "github.com/jmoiron/sqlx"
)

type Person struct {
    UserId   int    `db:"user_id"`
    Username string `db:"username"`
    Sex      string `db:"sex"`
    Email    string `db:"email"`
}

type Place struct {
    Country string `db:"country"`
    City    string `db:"city"`
    TelCode int    `db:"telcode"`
}

var Db *sqlx.DB

func init() {

    database, err := sqlx.Open("mysql", "root:@tcp(127.0.0.1:3306)/test")
    if err != nil {
        fmt.Println("open mysql failed,", err)
        return
    }

    Db = database
}

func main() {

    var person []Person
    err := Db.Select(&person, "select user_id, username, sex, email from person where user_id=?", 1)
    if err != nil {
        fmt.Println("exec failed, ", err)
        return
    }
    fmt.Println("select succ:", person)

    people := []Person{}
    Db.Select(&people, "SELECT * FROM person ORDER BY user_id ASC")
    fmt.Println(people)
    jason, john := people[0], people[1]
    fmt.Printf("%#v\n%#v", jason, john)
}
Nach dem Login kopieren

(löschen)

package main

import (
    "fmt"

    _ "github.com/go-sql-driver/mysql"
    "github.com/jmoiron/sqlx"
)

type Person struct {
    UserId   int    `db:"user_id"`
    Username string `db:"username"`
    Sex      string `db:"sex"`
    Email    string `db:"email"`
}

var Db *sqlx.DB

func init() {

    database, err := sqlx.Open("mysql", "root:@tcp(127.0.0.1:3306)/test")
    if err != nil {
        fmt.Println("open mysql failed,", err)
        return
    }

    Db = database
}

func main() {

    _, err := Db.Exec("delete from person where username=? limit 1", "suoning")
    if err != nil {
        fmt.Println("exec failed, ", err)
        return
    }

    fmt.Println("delete succ")
}
Nach dem Login kopieren

Transaktion

package main

import (
    "github.com/astaxie/beego/logs"
    _ "github.com/go-sql-driver/mysql"
    "github.com/jmoiron/sqlx"
)

var Db *sqlx.DB

func init() {
    database, err := sqlx.Open("mysql", "root:@tcp(127.0.0.1:3306)/test")
    if err != nil {
        logs.Error("open mysql failed,", err)
        return
    }
    Db = database
}

func main()  {
    conn, err := Db.Begin()
    if err != nil {
        logs.Warn("DB.Begin failed, err:%v", err)
        return
    }

    defer func() {
        if err != nil {
            conn.Rollback()
            return
        }
        conn.Commit()
    }()

    // do something
}
Nach dem Login kopieren

RabbitMQ

Installieren

go get "github.com/streadway/amqp"
Nach dem Login kopieren

Normaler Modus

Produzent:

package main

import (    "fmt"
    "log"
    "os"
    "strings"

    "github.com/streadway/amqp"
    "time")/*默认点对点模式*/func failOnError(err error, msg string) {    if err != nil {
        log.Fatalf("%s: %s", msg, err)
        panic(fmt.Sprintf("%s: %s", msg, err))
    }
}

func main() {    // 连接
    conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
    failOnError(err, "Failed to connect to RabbitMQ")
    defer conn.Close()    // 打开一个并发服务器通道来处理消息
    ch, err := conn.Channel()
    failOnError(err, "Failed to open a channel")
    defer ch.Close()    // 申明一个队列
    q, err := ch.QueueDeclare(        "task_queue", // name
        true,         // durable  持久性的,如果事前已经声明了该队列,不能重复声明
        false,        // delete when unused
        false,        // exclusive 如果是真,连接一断开,队列删除
        false,        // no-wait
        nil,          // arguments    )
    failOnError(err, "Failed to declare a queue")

    body := bodyFrom(os.Args)    // 发布
    err = ch.Publish(        "",     // exchange 默认模式,exchange为空
        q.Name,           // routing key 默认模式路由到同名队列,即是task_queue
        false,  // mandatory
        false,
        amqp.Publishing{            // 持久性的发布,因为队列被声明为持久的,发布消息必须加上这个(可能不用),但消息还是可能会丢,如消息到缓存但MQ挂了来不及持久化。            DeliveryMode: amqp.Persistent,
            ContentType:  "text/plain",
            Body:         []byte(body),
        })
    failOnError(err, "Failed to publish a message")
    log.Printf(" [x] Sent %s", body)
}

func bodyFrom(args []string) string {    var s string
    if (len(args) < 2) || os.Args[1] == "" {
        s = fmt.Sprintf("%s-%v","hello", time.Now())
    } else {
        s = strings.Join(args[1:], " ")
    }    return s
}
Nach dem Login kopieren

Verbraucher:

package main

import (
    "bytes"
    "fmt"
    "github.com/streadway/amqp"
    "log"
    "time"
)

/*
默认点对点模式
工作方,多个,拿发布方的消息
*/

func failOnError(err error, msg string) {
    if err != nil {
        log.Fatalf("%s: %s", msg, err)
        panic(fmt.Sprintf("%s: %s", msg, err))
    }
}

func main() {
    conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
    failOnError(err, "Failed to connect to RabbitMQ")
    defer conn.Close()

    ch, err := conn.Channel()
    failOnError(err, "Failed to open a channel")
    defer ch.Close()

    // 指定队列!
    q, err := ch.QueueDeclare(
        "task_queue", // name
        true,         // durable
        false,        // delete when unused
        false,        // exclusive
        false,        // no-wait
        nil,          // arguments
    )
    failOnError(err, "Failed to declare a queue")

    // Fair dispatch 预取,每个工作方每次拿一个消息,确认后才拿下一次,缓解压力
    err = ch.Qos(
        1,     // prefetch count
        0,     // prefetch size
        false, // global
    )
    failOnError(err, "Failed to set QoS")

    // 消费根据队列名
    msgs, err := ch.Consume(
        q.Name, // queue
        "",     // consumer
        false,  // auto-ack   设置为真自动确认消息
        false,  // exclusive
        false,  // no-local
        false,  // no-wait
        nil,    // args
    )
    failOnError(err, "Failed to register a consumer")

    forever := make(chan bool)

    go func() {
        for d := range msgs {
            log.Printf("Received a message: %s", d.Body)
            dot_count := bytes.Count(d.Body, []byte("."))
            t := time.Duration(dot_count)
            time.Sleep(t * time.Second)
            log.Printf("Done")

            // 确认消息被收到!!如果为真的,那么同在一个channel,在该消息之前未确认的消息都会确认,适合批量处理
            // 真时场景:每十条消息确认一次,类似
            d.Ack(false)
        }
    }()

    log.Printf(" [*] Waiting for messages. To exit press CTRL+C")
    <-forever
}
Nach dem Login kopieren

Abonnementmodus

Abonnement-Produzent:

package main

import (
    "fmt"
    "github.com/streadway/amqp"
    "log"
    "os"
    "strings"
    "time"
)

/*
广播模式
发布方
*/

func failOnError(err error, msg string) {
    if err != nil {
        log.Fatalf("%s: %s", msg, err)
        panic(fmt.Sprintf("%s: %s", msg, err))
    }
}

func main() {
    conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
    failOnError(err, "Failed to connect to RabbitMQ")
    defer conn.Close()

    ch, err := conn.Channel()
    failOnError(err, "Failed to open a channel")
    defer ch.Close()

    // 默认模式有默认交换机,广播自己定义一个交换机,交换机可与队列进行绑定
    err = ch.ExchangeDeclare(
        "logs",   // name
        "fanout", // type 广播模式
        true,     // durable
        false,    // auto-deleted
        false,    // internal
        false,    // no-wait
        nil,      // arguments
    )
    failOnError(err, "Failed to declare an exchange")

    body := bodyFrom(os.Args)

    // 发布
    err = ch.Publish(
        "logs", // exchange 消息发送到交换机,这个时候没队列绑定交换机,消息会丢弃
        "",     // routing key  广播模式不需要这个,它会把所有消息路由到绑定的所有队列
        false,  // mandatory
        false,  // immediate
        amqp.Publishing{
            ContentType: "text/plain",
            Body:        []byte(body),
        })
    failOnError(err, "Failed to publish a message")

    log.Printf(" [x] Sent %s", body)
}

func bodyFrom(args []string) string {
    var s string
    if (len(args) < 2) || os.Args[1] == "" {
        s = fmt.Sprintf("%s-%v","hello", time.Now())
    } else {
        s = strings.Join(args[1:], " ")
    }
    return s
}
Nach dem Login kopieren

Abonnierter Verbraucher:

package main

import (
    "fmt"
    "github.com/streadway/amqp"
    "log"
)

/*
广播模式
订阅方
*/

func failOnError(err error, msg string) {
    if err != nil {
        log.Fatalf("%s: %s", msg, err)
        panic(fmt.Sprintf("%s: %s", msg, err))
    }
}

func main() {
    conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
    failOnError(err, "Failed to connect to RabbitMQ")
    defer conn.Close()

    ch, err := conn.Channel()
    failOnError(err, "Failed to open a channel")
    defer ch.Close()

    // 同样要申明交换机
    err = ch.ExchangeDeclare(
        "logs",   // name
        "fanout", // type
        true,     // durable
        false,    // auto-deleted
        false,    // internal
        false,    // no-wait
        nil,      // arguments
    )
    failOnError(err, "Failed to declare an exchange")

    // 新建队列,这个队列没名字,随机生成一个名字
    q, err := ch.QueueDeclare(
        "",    // name
        false, // durable
        false, // delete when usused
        true,  // exclusive  表示连接一断开,这个队列自动删除
        false, // no-wait
        nil,   // arguments
    )
    failOnError(err, "Failed to declare a queue")

    // 队列和交换机绑定,即是队列订阅了发到这个交换机的消息
    err = ch.QueueBind(
        q.Name, // queue name  队列的名字
        "",     // routing key  广播模式不需要这个
        "logs", // exchange  交换机名字
        false,
        nil)
    failOnError(err, "Failed to bind a queue")

    // 开始消费消息,可开多个订阅方,因为队列是临时生成的,所有每个订阅方都能收到同样的消息
    msgs, err := ch.Consume(
        q.Name, // queue  队列名字
        "",     // consumer
        true,   // auto-ack  自动确认
        false,  // exclusive
        false,  // no-local
        false,  // no-wait
        nil,    // args
    )
    failOnError(err, "Failed to register a consumer")

    forever := make(chan bool)

    go func() {
        for d := range msgs {
            log.Printf(" [x] %s", d.Body)
        }
    }()

    log.Printf(" [*] Waiting for logs. To exit press CTRL+C")
    <-forever
}
Nach dem Login kopieren

RPC-Modus

RPC-Antworter:

package main

import (
    "fmt"
    "log"
    "strconv"

    "github.com/streadway/amqp"
)

/*
RPC模式
应答方
*/

func failOnError(err error, msg string) {
    if err != nil {
        log.Fatalf("%s: %s", msg, err)
        panic(fmt.Sprintf("%s: %s", msg, err))
    }
}

func fib(n int) int {
    if n == 0 {
        return 0
    } else if n == 1 {
        return 1
    } else {
        return fib(n-1) + fib(n-2)
    }
}

func main() {

    conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
    failOnError(err, "Failed to connect to RabbitMQ")
    defer conn.Close()

    ch, err := conn.Channel()
    failOnError(err, "Failed to open a channel")
    defer ch.Close()

    q, err := ch.QueueDeclare(
        "rpc_queue", // name
        false,       // durable
        false,       // delete when usused
        false,       // exclusive
        false,       // no-wait
        nil,         // arguments
    )
    failOnError(err, "Failed to declare a queue")

    // 公平分发 没有这个则round-robbin
    err = ch.Qos(
        1,     // prefetch count
        0,     // prefetch size
        false, // global
    )
    failOnError(err, "Failed to set QoS")

    // 消费,等待请求
    msgs, err := ch.Consume(
        q.Name, // queue
        "",     // consumer
        false,  // auto-ack
        false,  // exclusive
        false,  // no-local
        false,  // no-wait
        nil,    // args
    )
    failOnError(err, "Failed to register a consumer")

    forever := make(chan bool)

    go func() {
        //请求来了
        for d := range msgs {
            n, err := strconv.Atoi(string(d.Body))
            failOnError(err, "Failed to convert body to integer")

            log.Printf(" [.] fib(%d)", n)

            // 计算
            response := fib(n)

            // 回答
            err = ch.Publish(
                "",        // exchange
                d.ReplyTo, // routing key
                false,     // mandatory
                false,     // immediate
                amqp.Publishing{
                    ContentType:   "text/plain",
                    CorrelationId: d.CorrelationId,  //序列号
                    Body:          []byte(strconv.Itoa(response)),
                })
            failOnError(err, "Failed to publish a message")

            // 确认回答完毕
            d.Ack(false)
        }
    }()

    log.Printf(" [*] Awaiting RPC requests")
    <-forever
}
Nach dem Login kopieren

RPC-Anforderer:

package main

import (
    "fmt"
    "log"
    "math/rand"
    "os"
    "strconv"
    "strings"
    "time"

    "github.com/streadway/amqp"
)

/*
RPC模式
请求方
*/

func failOnError(err error, msg string) {
    if err != nil {
        log.Fatalf("%s: %s", msg, err)
        panic(fmt.Sprintf("%s: %s", msg, err))
    }
}

func randomString(l int) string {
    bytes := make([]byte, l)
    for i := 0; i < l; i++ {
        bytes[i] = byte(randInt(65, 90))
    }
    return string(bytes)
}

func randInt(min int, max int) int {
    return min + rand.Intn(max-min)
}

func fibonacciRPC(n int) (res int, err error) {

    conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
    failOnError(err, "Failed to connect to RabbitMQ")
    defer conn.Close()

    ch, err := conn.Channel()
    failOnError(err, "Failed to open a channel")
    defer ch.Close()

    // 队列声明
    q, err := ch.QueueDeclare(
        "",    // name
        false, // durable
        false, // delete when usused
        true,  // exclusive 为真即连接断开就删除
        false, // noWait
        nil,   // arguments
    )
    failOnError(err, "Failed to declare a queue")

    msgs, err := ch.Consume(
        q.Name, // queue
        "",     // consumer
        true,   // auto-ack
        false,  // exclusive   这个为真,服务器会认为这是该队列唯一的消费者
        false,  // no-local
        false,  // no-wait
        nil,    // args
    )
    failOnError(err, "Failed to register a consumer")

    corrId := randomString(32)

    err = ch.Publish(
        "",          // exchange
        "rpc_queue", // routing key
        false,       // mandatory
        false,       // immediate
        amqp.Publishing{
            ContentType:   "text/plain",
            CorrelationId: corrId,
            ReplyTo:       q.Name,
            Body:          []byte(strconv.Itoa(n)),
        })
    failOnError(err, "Failed to publish a message")

    for d := range msgs {
        if corrId == d.CorrelationId {
            res, err = strconv.Atoi(string(d.Body))
            failOnError(err, "Failed to convert body to integer")
            break
        }
    }

    return
}

func main() {
    rand.Seed(time.Now().UTC().UnixNano())

    n := bodyFrom(os.Args)

    log.Printf(" [x] Requesting fib(%d)", n)
    res, err := fibonacciRPC(n)
    failOnError(err, "Failed to handle RPC request")

    log.Printf(" [.] Got %d", res)
}

func bodyFrom(args []string) int {
    var s string
    if (len(args) < 2) || os.Args[1] == "" {
        s = "30"
    } else {
        s = strings.Join(args[1:], " ")
    }
    n, err := strconv.Atoi(s)
    failOnError(err, "Failed to convert arg to integer")
    return n
}
Nach dem Login kopieren

Empfohlen: Golang-Tutorial

Das obige ist der detaillierte Inhalt vonEinführung in die Funktionsweise von Golang mit Redis, MySQL und RabbitMQ. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

Video Face Swap

Video Face Swap

Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Wie kann ich Dateien mit Golang sicher lesen und schreiben? Wie kann ich Dateien mit Golang sicher lesen und schreiben? Jun 06, 2024 pm 05:14 PM

Das sichere Lesen und Schreiben von Dateien in Go ist von entscheidender Bedeutung. Zu den Richtlinien gehören: Überprüfen von Dateiberechtigungen, Schließen von Dateien mithilfe von Verzögerungen, Validieren von Dateipfaden, Verwenden von Kontext-Timeouts. Das Befolgen dieser Richtlinien gewährleistet die Sicherheit Ihrer Daten und die Robustheit Ihrer Anwendungen.

Wie konfiguriere ich den Verbindungspool für die Golang-Datenbankverbindung? Wie konfiguriere ich den Verbindungspool für die Golang-Datenbankverbindung? Jun 06, 2024 am 11:21 AM

Wie konfiguriere ich Verbindungspooling für Go-Datenbankverbindungen? Verwenden Sie den DB-Typ im Datenbank-/SQL-Paket, um eine Datenbankverbindung zu erstellen. Legen Sie MaxOpenConns fest, um die maximale Anzahl gleichzeitiger Verbindungen festzulegen. Legen Sie ConnMaxLifetime fest, um den maximalen Lebenszyklus der Verbindung festzulegen.

Golang Framework vs. Go Framework: Vergleich der internen Architektur und externen Funktionen Golang Framework vs. Go Framework: Vergleich der internen Architektur und externen Funktionen Jun 06, 2024 pm 12:37 PM

Der Unterschied zwischen dem GoLang-Framework und dem Go-Framework spiegelt sich in der internen Architektur und den externen Funktionen wider. Das GoLang-Framework basiert auf der Go-Standardbibliothek und erweitert deren Funktionalität, während das Go-Framework aus unabhängigen Bibliotheken besteht, um bestimmte Zwecke zu erreichen. Das GoLang-Framework ist flexibler und das Go-Framework ist einfacher zu verwenden. Das GoLang-Framework hat einen leichten Leistungsvorteil und das Go-Framework ist skalierbarer. Fall: Gin-Gonic (Go-Framework) wird zum Erstellen der REST-API verwendet, während Echo (GoLang-Framework) zum Erstellen von Webanwendungen verwendet wird.

Wie speichere ich JSON-Daten in einer Datenbank in Golang? Wie speichere ich JSON-Daten in einer Datenbank in Golang? Jun 06, 2024 am 11:24 AM

JSON-Daten können mithilfe der gjson-Bibliothek oder der json.Unmarshal-Funktion in einer MySQL-Datenbank gespeichert werden. Die gjson-Bibliothek bietet praktische Methoden zum Parsen von JSON-Feldern, und die Funktion json.Unmarshal erfordert einen Zieltypzeiger zum Unmarshalieren von JSON-Daten. Bei beiden Methoden müssen SQL-Anweisungen vorbereitet und Einfügevorgänge ausgeführt werden, um die Daten in der Datenbank beizubehalten.

Wie finde ich den ersten Teilstring, der mit einem regulären Golang-Ausdruck übereinstimmt? Wie finde ich den ersten Teilstring, der mit einem regulären Golang-Ausdruck übereinstimmt? Jun 06, 2024 am 10:51 AM

Die FindStringSubmatch-Funktion findet die erste Teilzeichenfolge, die mit einem regulären Ausdruck übereinstimmt: Die Funktion gibt ein Segment zurück, das die passende Teilzeichenfolge enthält, wobei das erste Element die gesamte übereinstimmende Zeichenfolge und die nachfolgenden Elemente einzelne Teilzeichenfolgen sind. Codebeispiel: regexp.FindStringSubmatch(text,pattern) gibt einen Ausschnitt übereinstimmender Teilzeichenfolgen zurück. Praktischer Fall: Es kann verwendet werden, um den Domänennamen in der E-Mail-Adresse abzugleichen, zum Beispiel: email:="user@example.com", pattern:=@([^\s]+)$, um die Übereinstimmung des Domänennamens zu erhalten [1].

Ist es vielversprechender, Java oder Golang von Front-End zu Back-End-Entwicklung zu verwandeln? Ist es vielversprechender, Java oder Golang von Front-End zu Back-End-Entwicklung zu verwandeln? Apr 02, 2025 am 09:12 AM

Backend Learning Path: Die Erkundungsreise von Front-End zu Back-End als Back-End-Anfänger, der sich von der Front-End-Entwicklung verwandelt, Sie haben bereits die Grundlage von Nodejs, ...

Wie verwende ich eine vordefinierte Zeitzone mit Golang? Wie verwende ich eine vordefinierte Zeitzone mit Golang? Jun 06, 2024 pm 01:02 PM

Die Verwendung vordefinierter Zeitzonen in Go umfasst die folgenden Schritte: Importieren Sie das Paket „time“. Laden Sie eine bestimmte Zeitzone über die LoadLocation-Funktion. Verwenden Sie die geladene Zeitzone für Vorgänge wie das Erstellen von Zeitobjekten, das Analysieren von Zeitzeichenfolgen und das Durchführen von Datums- und Uhrzeitkonvertierungen. Vergleichen Sie Daten mit unterschiedlichen Zeitzonen, um die Anwendung der vordefinierten Zeitzonenfunktion zu veranschaulichen.

Praktisches Tutorial zur Golang-Framework-Entwicklung: FAQs Praktisches Tutorial zur Golang-Framework-Entwicklung: FAQs Jun 06, 2024 am 11:02 AM

Häufig gestellte Fragen zur Go-Framework-Entwicklung: Framework-Auswahl: Hängt von den Anwendungsanforderungen und Entwicklerpräferenzen ab, z. B. Gin (API), Echo (erweiterbar), Beego (ORM), Iris (Leistung). Installation und Verwendung: Verwenden Sie den Befehl gomod, um das Framework zu installieren, zu importieren und zu verwenden. Datenbankinteraktion: Verwenden Sie ORM-Bibliotheken wie gorm, um Datenbankverbindungen und -operationen herzustellen. Authentifizierung und Autorisierung: Verwenden Sie Sitzungsverwaltungs- und Authentifizierungs-Middleware wie gin-contrib/sessions. Praktischer Fall: Verwenden Sie das Gin-Framework, um eine einfache Blog-API zu erstellen, die POST, GET und andere Funktionen bereitstellt.

See all articles