Heim  >  Artikel  >  Backend-Entwicklung  >  Implementierung eines hochskalierbaren verteilten Bildverarbeitungssystems: Anwendung und Praxis von Go-Zero

Implementierung eines hochskalierbaren verteilten Bildverarbeitungssystems: Anwendung und Praxis von Go-Zero

WBOY
WBOYOriginal
2023-06-23 11:57:271334Durchsuche

Mit der Entwicklung moderner Technologie spielt die Bildverarbeitungstechnologie in allen Lebensbereichen eine immer größere Rolle. Von Überwachungssystemen in Smart Cities über Diagnose und Behandlung medizinischer Bildgebung bis hin zu Spielen und Film- und Fernsehproduktionen in der Unterhaltungsindustrie gehören Bildverarbeitungsalgorithmen zu den unverzichtbaren Kerntechnologien. Mit dem Wachstum der Bilddaten und der Anzahl der Benutzer sind herkömmliche Bildverarbeitungslösungen jedoch nach und nach nicht mehr in der Lage, die Anforderungen an hohe Parallelität, geringe Latenz und hohe Skalierbarkeit zu erfüllen. Daher sind verteilte Bildverarbeitungssysteme nach und nach zu einer Mainstream-Lösung geworden.

Unter vielen verteilten Bildverarbeitungs-Frameworks ist Go-Zero ein Back-End-Entwicklungs-Framework, das Aufmerksamkeit verdient. Es bietet einen vollständigen Satz verteilter Microservice-Lösungen, einschließlich API-Gateway, Service-Governance, Strombegrenzung und Leistungsschalter sowie massiver Datenspeicherung und verteilte Transaktionen und andere Funktionen. Bei der Entwicklung und Anwendung von Bildverarbeitungssystemen kann die umfassende Unterstützung von go-zero die Zuverlässigkeit und Leistung des Systems erheblich verbessern. In diesem Artikel werden die Anwendung und Praxis von Go-Zero in der verteilten Bildverarbeitung aus verschiedenen Aspekten wie Anwendungsszenarien, Architekturdesign, Technologieauswahl und Codeimplementierung vorgestellt.

1. Anwendungsszenarien

Bildverarbeitungssysteme sind typische datenintensive und rechenintensive Anwendungen. Zu den Hauptproblemen gehören:

  1. Große Datenmengen und hohe Anforderungsgleichzeitigkeit: Für Echtzeitüberwachungssysteme B. Live-Übertragungssysteme, können Hunderttausende oder sogar Millionen von Bilddaten pro Sekunde erzeugen. Sie müssen in der Lage sein, diese Daten schnell zu verarbeiten und Dienste mit hohem Durchsatz und geringer Latenz bereitzustellen.
  2. Komplexe Aufgabenberechnungen: Bei rechenintensiven Aufgaben wie komplexen Bildalgorithmen und Deep-Learning-Modellen ist es notwendig, verschiedene Bildverarbeitungsvorgänge wie Bildmerkmalsextraktion, Klassifizierung, Erkennung und Synthese schnell und genau abzuschließen.
  3. Hohe Verfügbarkeit und hohe Skalierbarkeit: Bei sich ändernden Geschäftsanforderungen muss das System hochverfügbar und skalierbar sein, in der Lage sein, ungewöhnliche Situationen wie plötzlichen Datenverkehr und Knotenausfälle zu bewältigen und kontinuierliche und stabile Dienste bereitzustellen.

go-zero kann auf eine Vielzahl von Szenarien angewendet werden, in denen die oben genannten Probleme auftreten, z. B.:

  1. Bildklassifizierungssystem: Bilder klassifizieren, z. B. automatische Erkennung von Gesichtern, Automodellen, Lebensmitteln usw.
  2. Bildsynthesesystem: Kombinieren Sie mehrere Bilder zu einem Bild, z. B. Bildzusammenfügung, Bildsynthese für konkrete Produkte usw.
  3. Überwachungssystem: Führen Sie eine Echtzeitverarbeitung von Bildern durch, z. B. Personenstromstatistiken, Texterkennung usw., und wandeln Sie Bilddaten in nutzbare statistische Daten um.

2. Architekturdesign

Um die oben genannten Anforderungen zu erfüllen, müssen wir ein zuverlässiges, skalierbares und effizientes verteiltes Bildverarbeitungssystem entwerfen. Mit Hilfe von Go-Zero können wir das folgende Infrastrukturdesign erreichen:

  1. API-Gateway: Bietet Web-API-Schnittstellen-Gateway-Dienste, um Anfragen von verschiedenen Clients einheitlich zu verwalten.
  2. RPC-Dienst: Geschäftsdienst, der für bestimmte Bildverarbeitungsaufgaben verantwortlich ist und ein verteiltes Microservice-Modell verwendet, das je nach Geschäft aufgeteilt und bereitgestellt wird.
  3. Konfigurationsdienst: Konfigurationsdienst, der öffentliche Konfigurationen einheitlich verwaltet und verteilt.
  4. Ressourcenmanagement: Ressourcenmanagement, einschließlich Überwachung, Flusskontrolle, Leistungsschalterverschlechterung, Strombegrenzung und andere Funktionen, um eine angemessene Nutzung der Systemressourcen und eine stabile Leistung sicherzustellen.
  5. Speicherdienst: Speichern Sie die verarbeiteten Daten im Cloud-verteilten, gemeinsam genutzten Speichersystem, um den späteren Geschäftszugriff und die Abfrage zu erleichtern.

3. Technologieauswahl

Beim Entwerfen spezifischer technischer Lösungen können wir zunächst einige traditionelle Technologien und Algorithmen auswählen, die für die Bildverarbeitung geeignet sind, und dann das von Go-Zero bereitgestellte Microservice-Framework und einige gängige verteilte Technologien verwenden, um die Funktionen zu realisieren das gesamte System.

Um dies zu erreichen, können insbesondere die folgenden Technologien eingesetzt werden:

  1. Bildverarbeitungsalgorithmus: Mithilfe traditioneller Bildverarbeitungsalgorithmen wie OpenCV, PIL und anderen Bibliotheken sowie einiger Deep-Learning-Modelle werden die Merkmalsextraktion, Klassifizierung, Erkennung usw. durchgeführt Synthese von Bildern kann erreicht werden und andere Bildverarbeitungsaufgaben.
  2. Microservice-Framework: Mit dem Microservice-Framework von Go-Zero können Sie schnell ein verteiltes Bildverarbeitungssystem aufbauen, um Aufgabenteilung, Geschäftslogikentwicklung, Lastausgleich, Fehlerbehebung und andere Funktionen zu erreichen.
  3. Verteilte Technologie: Mit verteilten Koordinationstechnologien wie etcd und zookeeper können Funktionen wie Dienstregistrierung und -erkennung, Konfigurationsverwaltung usw. realisiert werden, wodurch das System stabiler und zuverlässiger wird.
  4. Speicherschicht: Sie können ein verteiltes gemeinsames Speichersystem wie FastDFS usw. auswählen, um verarbeitete Daten gemeinsam zu nutzen und zu verwalten.

4. Code-Implementierung

Bei der spezifischen Implementierung der oben genannten Funktionen können wir das von go-zero bereitgestellte Code-Framework verwenden, um spezifische Geschäftslogik und technische Implementierung abzuschließen. Das Folgende ist ein Beispielprogramm, das den Entwicklungsprozess eines vollständigen verteilten Bildverarbeitungssystems darstellt.

Führen Sie zunächst die erforderlichen Framework- und Abhängigkeitspakete in main.go ein:

package main

import (
    "github.com/tal-tech/go-zero/core/conf"
    "github.com/tal-tech/go-zero/core/logx"
    "github.com/tal-tech/go-zero/rest"
)

func main() {
    logx.Disable()
    var c Config
    conf.MustLoad(&c)

    server := rest.MustNewServer(c.RestConf)
    defer server.Stop()

    InitHandlers(server.Group("/"))

    go func() {
        select {
        case <-server.Done():
            logx.Info("Stopping...")
        }
    }()
    server.Start()
}

Darunter speichert die Config-Struktur die Systemkonfigurationsinformationen und wird in config.toml konfiguriert Die spezifische Geschäftslogik wird in der InitHandlers-Funktion implementiert.

func InitHandlers(group *rest.Group) {
    group.POST("/image/:type", func(ctx *rest.Context) {
    // 业务逻辑:根据type参数分发图像任务,调用具体的RPC服务进行处理
    })
}

Als nächstes wird die spezifische Geschäftslogik im Handler-Paket implementiert.

package handlers

import (
    "context"
    "encoding/base64"
    "github.com/tal-tech/go-zero/core/logx"
    "github.com/tal-tech/go-zero/rest/httpx"
    "github.com/tal-tech/go-zero/zrpc"
    "github.com/yanyiwu/gojieba"
    "go-zero-example/service/image/api/internal/logic"
    "go-zero-example/service/image/api/internal/svc"
    "go-zero-example/service/image/rpc/image"
)

const (
    FACE_DETECT = iota
    FACE_RECOGNITION
    COLOR_DETECT
)

var jieba = gojieba.NewJieba()

type ImageType int32

type ImageHandler struct {
    ctx    context.Context
    svcCtx *svc.ServiceContext
}

func NewImageHandler(ctx context.Context, svcCtx *svc.ServiceContext) *ImageHandler {
    return &ImageHandler{ctx: ctx, svcCtx: svcCtx}
}

func (l *ImageHandler) Handle(reqTypes []ImageType, base64Data string) (*image.Data, error) {
    req := logic.ImageReq{
        ReqTypes:   reqTypes,
        Base64Data: base64Data,
    }

    // 将图像处理请求分发给所有RPC服务
    results := make([]*image.Data, 0, len(reqTypes))
    for _, reqType := range reqTypes {
        data, err := l.svcCtx.ImageRpcClient.DoImage(l.ctx, &image.ImageReq{
            ImageType: int32(reqType),
            ImageData: base64Data,
        })
        if err != nil {
            logx.WithError(err).Warnf("image rpc call failed: %v", data)
            return nil, httpx.Error(500, "服务内部错误")
        }

        results = append(results, data)
    }

    // 直接返回结果
    return logic.MergeResults(results), nil
}

// 字符串转float
func str2float(str string, defVal float64) float64 {
    if len(str) == 0 {
        return defVal
    }
    val, err := strconv.ParseFloat(str, 64)
    if err != nil {
        return defVal
    }
    return val
}

// 字符串转int
func str2int(str string, defVal int64) int64 {
    if len(str) == 0 {
        return defVal
    }
    val, err := strconv.ParseInt(str, 10, 64)
    if err != nil {
        return defVal
    }
    return val
}

// 合并处理结果
func (l *ImageHandler) MergeResults(datas []*image.Data) *image.Data {
    if len(datas) == 1 {
        return datas[0]
    }
    mergeData := &image.Data{
        MetaData: &image.MetaData{
            Status:  0,
            Message: "success",
        },
    }

    for _, data := range datas {
        if data.MetaData.Status != 0 {
            return data // 异常情况
        }
        switch data.DataType {
        case image.DataType_STRING:
            if mergeData.StringData == nil {
                mergeData.StringData = make(map[string]string)
            }
            for k, v := range data.StringData {
                mergeData.StringData[k] = v
            }
        case image.DataType_NUMBER:
            if mergeData.NumberData == nil {
                mergeData.NumberData = make(map[string]float64)
            }
            for k, v := range data.NumberData {
                mergeData.NumberData[k] = v
            }
        case image.DataType_IMAGE:
            if mergeData.ImageData == nil {
                mergeData.ImageData = make([]*image.ImageMeta, 0)
            }
            mergeData.ImageData = append(mergeData.ImageData, data.ImageData...)
        }
    }
    return mergeData
}

Schließlich können wir die spezifische RPC-Dienstschnittstelle in image.proto definieren, wie unten gezeigt:

syntax = "proto3";

package image;

service ImageApi {
    rpc DoImage(ImageReq) returns (Data) {}
}

message ImageReq {
    int32 image_type = 1;
    string image_data = 2;
}

message ImageMetaData {
    int32 status = 1;
    string message = 2;
}

message Data {
    ImageMetaData meta_data = 1;
    DataType data_type = 2;
    map<string, string> string_data = 3; 
    map<string, float> number_data = 4;
    repeated ImageMeta image_data = 5;

}

// 可返回的数据类型
enum DataType {
    STRING = 0;
    NUMBER = 1;
    IMAGE = 2;
}

message ImageMeta {
    string url = 1;
    int32 width = 2;
    int32 height = 3;
}

至此,一个完整的分布式图像处理系统就具备了基础的功能和业务逻辑,可以部署到服务器中,供用户使用。

五、总结

本文介绍了go-zero在分布式图像处理中的应用和实践,从应用场景、架构设计、技术选型、代码实现等方面对图像处理系统进行了详细阐述。针对图像处理系统的特点,go-zero提供了一套全面的分布式微服务解决方案,可以快速搭建高可扩展性的系统,提高系统的性能和可靠性,同时也为开发者提供了产品支持和服务保障,适用于多种应用场景。

Das obige ist der detaillierte Inhalt vonImplementierung eines hochskalierbaren verteilten Bildverarbeitungssystems: Anwendung und Praxis von Go-Zero. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
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