Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Tulis sistem pemesejan yang cekap menggunakan bahasa Go

Tulis sistem pemesejan yang cekap menggunakan bahasa Go

PHPz
PHPzasal
2023-06-15 12:36:121410semak imbas

Dengan perkembangan Internet, sistem pemesejan semakin digunakan dalam pelbagai bidang. Sistem pemesejan boleh melaksanakan komunikasi tak segerak untuk meningkatkan prestasi dan kebolehpercayaan sistem Ia juga boleh mencapai penyahgandingan untuk memudahkan pengembangan dan penyelenggaraan sistem. Bahasa Go mempunyai ciri coroutine dan saluran, menjadikannya sangat cekap dan fleksibel dalam melaksanakan sistem mesej. Artikel ini akan memperkenalkan cara menggunakan bahasa Go untuk menulis sistem pemesejan yang cekap.

1. Fahami seni bina asas sistem mesej

Seni bina asas sistem mesej terdiri daripada tiga bahagian: penerbit mesej, pengguna mesej dan baris gilir mesej. Penerbit mesej menghantar mesej ke baris gilir mesej untuk penyimpanan, dan pengguna mesej memperoleh mesej daripada baris gilir mesej untuk penggunaan. Barisan gilir mesej memainkan peranan penimbalan dan penyahgandingan, yang boleh menjadikan keupayaan pemprosesan penerbit mesej dan pengguna mesej tidak konsisten, mesej cache semasa tempoh puncak dan memastikan kebolehpercayaan dan urutan mesej.

2. Cipta sistem pemesejan menggunakan bahasa Go

  1. Pasang baris gilir mesej RabbitMQ

Memandangkan RabbitMQ ialah sumber terbuka, boleh dipercayai, cekap dan berskala Broker mesej, jadi kami memilih untuk menggunakan baris gilir mesej ini untuk melaksanakan sistem pemesejan kami di sini. Anda boleh memuat turun RabbitMQ dari laman web rasmi https://www.rabbitmq.com/.

  1. Membuat pengeluar mesej dan pengguna mesej

Sangat mudah untuk menulis pengeluar mesej dan pengguna mesej menggunakan bahasa Go. Berikut ialah contoh kod untuk pengeluar mesej ringkas:

package main

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

func failOnError(err error, msg string) {
    if err != nil {
        log.Fatalf("%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(
        "hello", // queue name
        false,   // durable
        false,   // delete when unused
        false,   // exclusive
        false,   // no-wait
        nil,     // arguments
    )
    failOnError(err, "Failed to declare a queue")

    body := "Hello World!"
    err = ch.Publish(
        "",     // exchange
        q.Name, // routing key
        false,  // mandatory
        false,  // immediate
        amqp.Publishing {
            ContentType: "text/plain",
            Body:        []byte(body),
        })
    failOnError(err, "Failed to publish a message")
}

Kod di atas bersambung ke pelayan RabbitMQ, membuat baris gilir bernama "hello", dan menghantar mesej "Hello World!"

Berikut ialah contoh kod untuk pengguna mesej ringkas:

package main

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

func failOnError(err error, msg string) {
    if err != nil {
        log.Fatalf("%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(
        "hello", // queue name
        false,   // durable
        false,   // delete when unused
        false,   // exclusive
        false,   // no-wait
        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,    // arguments
    )
    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)
        }
    }()

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

Kod di atas bersambung ke pelayan RabbitMQ, mencipta baris gilir bernama "hello", dan mendapatkan mesej daripada baris gilir . Selagi terdapat mesej dalam baris gilir, pengguna mesej boleh mengambilnya dengan segera.

  1. Menggunakan coroutine dan saluran untuk melaksanakan pemprosesan serentak

Ciri coroutine dan saluran dalam bahasa Go boleh membantu kami melaksanakan pemprosesan serentak dalam sistem mesej. Coroutine adalah seperti benang ringan yang boleh mencapai pemprosesan serentak yang tinggi. Saluran boleh berfungsi sebagai jambatan komunikasi antara coroutine untuk mencapai penghantaran data serentak.

Berikut ialah contoh kod yang menggunakan coroutine dan saluran untuk melaksanakan pemprosesan serentak:

package main

import (
    "log"
    "math/rand"
    "time"
    "github.com/streadway/amqp"
)

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

func publish(i int) {
    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(
        "hello", // queue name
        false,   // durable
        false,   // delete when unused
        false,   // exclusive
        false,   // no-wait
        nil,     // arguments
    )
    failOnError(err, "Failed to declare a queue")

    body := "Hello World " + strconv.Itoa(i) + "!"
    err = ch.Publish(
        "",     // exchange
        q.Name, // routing key
        false,  // mandatory
        false,  // immediate
        amqp.Publishing {
            ContentType: "text/plain",
            Body:        []byte(body),
        })
    failOnError(err, "Failed to publish a message")
}

func consume() {
    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(
        "hello", // queue name
        false,   // durable
        false,   // delete when unused
        false,   // exclusive
        false,   // no-wait
        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,    // arguments
    )
    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)
        }
    }()

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

func main() {
    rand.Seed(time.Now().UnixNano())
    
    for i := 0; i < 10; i++ {
        go publish(i)
    }

    go consume()

    forever := make(chan bool)
    <-forever
}

Dalam kod di atas, kami mencipta 10 coroutine untuk menghantar mesej ke baris gilir mesej pada masa yang sama, dan mencipta Coroutine lain untuk mendapatkan mesej untuk kegunaan. Ini sangat meningkatkan keupayaan pemprosesan serentak sistem mesej.

3. Ringkasan

Dalam artikel ini, kami memperkenalkan cara menggunakan bahasa Go untuk menulis sistem pemesejan yang cekap. Dengan menggunakan ciri broker mesej RabbitMQ, coroutine dan saluran, kami boleh dengan mudah melaksanakan sistem pemesejan berkonkurensi tinggi dan kebolehpercayaan tinggi. Jika anda perlu melaksanakan komunikasi mesej tak segerak dalam projek semasa anda, maka bahasa Go ialah pilihan yang baik.

Atas ialah kandungan terperinci Tulis sistem pemesejan yang cekap menggunakan bahasa Go. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn