Gründer der Cloud-nativen Mikroservice-Konstruktionspraxis für Wertpapier- und Finanztechnologie

Dieser Artikel basiert auf der Rede „Financial Technology Go Microservices“, die Liu Yi, leitender Forschungs- und Entwicklungsingenieur des Founder Securities Financial Technology Engineering Institute, auf dem CloudWeGo Technology Salon „Cloud Native✖️Microservice Architecture and Technical Practice in the AI ​​​​Era“ gehalten hat Veranstaltung in Peking am 30. März 2024. Zusammengestellt aus „Construction Practice“.

Überblick: In diesem Artikel werden die praktischen Erfahrungen des Founder Securities Financial Technology Engineering Institute beim Aufbau cloudnativer Mikrodienste ausführlich vorgestellt. Der Austausch umfasst drei Aspekte:

  1. Microservice-Governance-Arbeit
  2. Observability-Arbeit bei Microservices
  3. Die oben genannten Funktionen des Microservice-Schnittstellenmanagements sind vereinheitlicht und in die Quark-Entwicklungsplattform von Founder integriert.

Einführung in die Praxis des Microservice-Aufbaus von Founder Securities

Anfang 2023 haben wir mit dem Aufbau eines Microservice-Systems begonnen, bei dem das Registrierungszentrum ZooKeeper verwendet und die Web- und RPC-Anwendungsframeworks Hertz bzw. Kitex von CloudWeGo verwenden .    

Derzeit sind wir in den Tiefwasserbereich des Microservice-Aufbaus eingestiegen, der hauptsächlich Microservice-Governance , Observability-Fähigkeiten , Schnittstellenmanagement und andere verwandte Arbeiten umfasst. Im Folgenden werden die Konzepte und Implementierungsprinzipien detailliert vorgestellt.

Aufbau von Microservice-Governance-Fähigkeiten

Konzept

Unter der Microservice-Architektur wird mit zunehmendem Geschäftsvolumen auch die Anzahl der Dienste schrittweise zunehmen. Vor diesem Hintergrund wird es mit zunehmender Geschäftsentwicklung immer schwieriger, Dienste zu verwalten und zu kontrollieren. Die Aufgabe der Service-Governance besteht darin, eine Reihe von Problemen zu lösen, die durch die Aufteilung von Diensten verursacht werden Bietet Service-Registrierung und -Erkennung, Lastausgleich, Service-Leistungsschalter, Service-Verschlechterung, Service-Strombegrenzung usw. Die von der Quark-Plattform bereitgestellten Timeout-, Wiederholungs- und serverseitigen Strombegrenzungsfunktionen basieren alle auf den zugehörigen Funktionen von Kitex . Das derzeit verwendete Registrierungszentrum ist ZooKeeper (abgekürzt als zk), sodass die zugehörige dynamische Konfiguration ebenfalls mit Hilfe implementiert wird von zk, durch Schreiben Sie die Konfiguration in zk, um den Server und den Client zu benachrichtigen, um die Aktivierung verwandter Funktionen abzuschließen.  

einführen

  1. Ablaufsteuerung

    Die Granularität der Flusskontrolle ist die Dienstebene. Wie in der folgenden Abbildung dargestellt, kann der Dienst bis zu 1.000 Anforderungen pro Sekunde verarbeiten, und übermäßige Anforderungen werden direkt abgeschaltet: huaxing_ratelimit

  2. Versuchen Sie es erneut mit der Konfiguration

    Die Granularität der Wiederholungskonfiguration liegt auf der Methodenebene, die verwendet wird, um zu konfigurieren, wie wiederholt werden soll, wenn der aktuelle Dienst keine Anfrage an eine Methode des angegebenen Dienstes stellen kann: huaxing_retry

  3. Timeout-Konfiguration

    Die Granularität der Timeout-Konfiguration liegt auf der Methodenebene, die verwendet wird, um die maximale Zeit zu konfigurieren, die der aktuelle Dienst benötigt, um eine Methode des angegebenen Dienstes anzufordern. Wenn dieser Wert überschritten wird, wird der aktuelle Dienst getrennt: siehe Konfiguration Beschreibung für die spezifischen Funktionen jeder Konfiguration. huaxing_timeout 

Umsetzungsprinzipien und Details

Sowohl die Serverseite als auch die Clientseite vervollständigen die dynamische Injektion relevanter Konfigurationen durch Erweiterung der Kitex -Suite.  

serverseitig

Konfigurieren Sie den Kitex-Server mit dem folgenden Code:

server.WithSuite(zooKeeperServer.NewSuite("Kitex-server", zooKeeperClient))
Kopieren

Darunter zooKeeperServer.NewSuite("Kitex-server", zooKeeperClient)wird eine Suite-Instanz zurückgegeben und die in den Server injizierte Limiter-Konfiguration wird einbezogen: Options 

func (s *zooKeeperServerSuite) Options() []server.Option {
    opts := make([]server.Option, 0, 2)
    // WithLimiter实现中,在zk中注册了监听器,每当数据变化,动态更新Limiter的相关配置,以达到限流目的
    opts = append(opts, WithLimiter(s.service, s.zooKeeperClient, s.opts))
    return opts
}
Kopieren

Basierend auf dem obigen Inhalt kann festgestellt werden, dass in der serverseitigen Suite standardmäßig nur Begrenzer konfiguriert sind. Das Kitex-  Framework unterstützt derzeit nur zwei Arten von Begrenzern:

  1. Verbindungsbegrenzer (begrenzen Sie die maximale Anzahl von Verbindungen)
  2. Qps-Limiter (maximale QPS begrenzen)

Bei Verwendung von zk als Registrierungszentrum können beide dynamisch über die Konfiguration angepasst werden. Nach Änderungen werden die Konfigurationswerte über den Listener von zk abgerufen:

// zk数据变化时的回调方法
onChangeCallback := func(restoreDefault bool, data string, parser zooKeeper.ConfigParser) {
   lc := &limiter.LimiterConfig{}
   if !restoreDefault && data != "" {
      err := parser.Decode(data, lc)
      if err != nil {
         klog.Warnf("[zooKeeper] %s server zooKeeper config: unmarshal data %s failed: %s, skip...", dest, data, err)
         return
      }
   }
   // 将zk中的数据动态更新到配置中
   opt.MaxConnections = int(lc.ConnectionLimit)
   opt.MaxQPS = int(lc.QPSLimit)
   u := updater.Load()
   if u == nil {
      klog.Warnf("[zooKeeper] %s server zooKeeper limiter config failed as the updater is empty", dest)
      return
   }
   if !u.(limit.Updater).UpdateLimit(opt) {
      klog.Warnf("[zooKeeper] %s server zooKeeper limiter config: data %s may do not take affect", dest, data)
   }
}
// path,对于limiter,其值为:/KitexConfig/{ServiceName}/limit
zooKeeperClient.RegisterConfigCallback(context.Background(), path, uniqueID, onChangeCallback)
Kopieren

Client-Seite

Ähnlich wie auf der Serverseite hat auch die Clientseite die gleiche Konfiguration:

bizService.NewClient("Kitex-client",
client.WithSuite(zooKeeperclient.NewSuite("Kitex-server", "Kitex-client", zooKeeperClient)))
Kopieren

Die Suite auf der Clientseite enthält die folgenden Optionen:

func (s *zooKeeperClientSuite) Options() []client.Option {
    opts := make([]client.Option, 0, 7)
    opts = append(opts, WithRetryPolicy(s.service, s.client, s.zooKeeperClient, s.opts)...)
    opts = append(opts, WithRPCTimeout(s.service, s.client, s.zooKeeperClient, s.opts)...)
    opts = append(opts, WithCircuitBreaker(s.service, s.client, s.zooKeeperClient, s.opts)...)
    return opts
}
Kopieren

Das heißt, der Client unterstützt drei dynamische Konfigurationen: Wiederholung, Zeitüberschreitung und Leistungsschalter. Die entsprechende Verarbeitung erfolgt über die Rückrufmethode des zk-Clients, um den Effekt einer dynamischen Aktualisierung zu erzielen.

Zusätzliche Hinweise zur Timeout-Konfiguration

Für Timeout lautet die spezifische Implementierung seiner Konfigurationsmethode wie folgt:

func WithRPCTimeout(dest, src string, zooKeeperClient zooKeeper.Client, opts utils.Options) []client.Option {
    // ...
    return []client.Option{
        client.WithTimeoutProvider(initRPCTimeoutContainer(path, uid, dest, zooKeeperClient)),
        client.WithCloseCallbacks(func() error {
            // cancel the configuration listener when client is closed.
            zooKeeperClient.DeregisterConfig(path, uid)
            return nil
        }),
    }
}
Kopieren

client.WithTimeoutProviderAbschließend wird die spezifische Konfiguration im Zusammenhang mit dem Timeout durch Aufrufen der von Kitex bereitgestellten Methode abgeschlossen. Für Timeouts gibt es folgende unterschiedliche Konfigurationsmethoden:

func WithRPCTimeout(d time.Duration) Option {
    // ...
}

func WithConnectTimeout(d time.Duration) Option {
    // ...
}

func WithTimeoutProvider(p rpcinfo.TimeoutProvider) Option {
    // ...
}
Kopieren

Unter anderem WithTimeoutProviderwird das eingestellte Timeout WithRPCTimeoutdurch den eingestellten Wert von überschrieben. Wenn also oder WithConnectTimeoutbeim Erstellen des Kitex-Clients aufgerufen wird, wird die dynamische Konfiguration nicht wirksam.WithRPCTimeoutWithConnectTimeout

Konfigurationsanleitung

Auszeit

Entsprechender ZK-Knoten:/kitexConfig/{ClientName}/{ServiceName}/rpc_timeout

Das geschriebene Konfigurationsformat lautet wie folgt:

{
  "*": {
    "conn_timeout_ms": 100,
    "rpc_timeout_ms": 800
  },
  "GetDemoInfo": {
    "rpc_timeout_ms": 300
  },
  "GetDemoInfo3": {
    "rpc_timeout_ms": 300
  }
}
Kopieren

Feldbedeutung : die maximale Wartezeit zum Aufbau einer neuen Verbindung: die maximale Zeit für einen RPC-Aufruf; conn_timeout_ms rpc_timeout_ms

Wiederholen

Entsprechender ZK-Knoten:/kitexConfig/{ClientName}/{ServiceName}/retry

Das geschriebene Konfigurationsformat lautet wie folgt:

{
  "GetDemoInfo": {
    "enable": true,
    "type": 0,
    "failure_policy": {
      "stop_policy": {
        "max_retry_times": 2,
        "max_duration_ms": 9000,
        "cb_policy": {
          "error_rate": 0.1
        }
      }
    }
  },
  "GetDemoInfo5": {
    "enable": true,
    "type": 0,
    "failure_policy": {
      "stop_policy": {
        "max_retry_times": 2,
        "max_duration_ms": 9000,
        "cb_policy": {
          "error_rate": 0.1
        }
      }
    }
  }
}
Kopieren

Feldbedeutung

Konfigurationselemente Standardwert veranschaulichen Grenze
max_retry_times 2 Die maximale Anzahl von Wiederholungsversuchen, mit Ausnahme der ersten Anfrage. Wenn die Konfiguration auf 0 eingestellt ist, bedeutet dies, dass der Wiederholungsversuch beendet wird. Zulässige Werte: [0-5]
max_duration_ms 0 Die kumulative maximale verstrichene Zeit, einschließlich der verstrichenen Zeit für die erste fehlgeschlagene Anfrage und die Wiederholungsanforderung. Wenn die verstrichene Zeit das Limit erreicht, werden nachfolgende Wiederholungsversuche gestoppt. 0 bedeutet keine Begrenzung. Hinweis: Falls konfiguriert, muss dieses Konfigurationselement größer als das Anforderungszeitlimit sein.  
Fehlerrate 10 % Schwellenwert für die Fehlerrate des Leistungsschalters bei erneuten Versuchen. Wenn die Fehlerrate der Anforderung auf Methodenebene den Schwellenwert überschreitet, werden Wiederholungsversuche gestoppt. Gesetzliche Werte: (0-30 %]

Begrenzend

Diese Konfiguration ist eine globale Konfiguration für den Dienst, daher enthält der zk-Knotenpfad nur serviceName:/kitexConfig/{ServiceName}/limit

Das geschriebene Konfigurationsformat lautet wie folgt:

{
  "qps_limit": 100
}
Kopieren

Aufbau von Microservice-Beobachtbarkeitsfähigkeiten

Konzept

Der Aufbau von Service Observability bezieht sich auf die Einrichtung und Verbesserung von Überwachungs-, Protokollierungs-, Nachverfolgungs- und anderen Tools und Technologien in verteilten Systemen, um den Betriebsstatus und die Leistungsindikatoren des Systems umfassend und zeitnah zu verstehen.

Ein vollständiges Beobachtungstool kann den Geschäftssystemen viele Vorteile bringen:

  1. Fähigkeit, Probleme rechtzeitig zu erkennen und zu lösen;
  2. Ermöglichen Sie dem Team ein klareres Verständnis des Gesamtbetriebs und der internen Interaktionen des Systems.
  3. Kann den Laststatus, die Ressourcennutzung und Trendänderungen des Systems verstehen, um die Kapazitätsplanung und Ressourcenoptimierung zu unterstützen;
  4. Durch die Aufzeichnung der Betriebsprotokolle und Anforderungsspuren des Systems über das Protokoll- und Verfolgungssystem können Benutzerbetriebsverhalten, ungewöhnliche Anforderungen und Sicherheitsereignisse verfolgt und analysiert werden, um die Sicherheit und Zuverlässigkeit des Systems zu verbessern.

einführen

Dienstdetails werden verwendet, um den Gesamtbetrieb des Dienstes selbst anzuzeigen, einschließlich goldener Überwachungsindikatoren (QPS, Latenz und Fehlerverhältnis), SLO und laufzeitbezogener Informationen usw.: huaxing_grafana

Das Topologiediagramm wird verwendet, um die Upstream- und Downstream-Abhängigkeiten zwischen Diensten anzuzeigen: huaxing_topology

Anrufkettendaten enthalten detaillierte Informationen zu jedem Anruf zwischen Diensten: huaxing_trace

Umsetzungsprinzipien und Details

huaxing_otel

Derzeit ist der OpenTelemetry- Client in den Vorlagencode integriert , und die generierten Hertz- und Kitex- Dienste verfügen standardmäßig über beobachtbare Datenberichtsfunktionen (Metriken + Tracing).    

Ausführliche Informationen finden Sie unter: kitex-contrib/obs-opentelemetry  und hertz-contrib/obs-opentelemetry 

OpenTelemetry  (OTel) ist ein Open-Source-Observability-Framework, das es Entwicklungsteams ermöglicht, Telemetriedaten in einem einheitlichen Format zu generieren, zu verarbeiten und zu übertragen. Es wurde von der Cloud Native Computing Foundation (CNCF) entwickelt, um Standardprotokolle und Tools zum Sammeln und Senden von Metriken, Protokollen und Spuren an Überwachungsplattformen bereitzustellen. OpenTelemetry bietet herstellerunabhängige SDKs, APIs und Tools. OpenTelemetry entwickelt sich schnell zum dominierenden Datenstandard für Observability-Telemetriedaten für Cloud-native Anwendungen. Die Einführung von OpenTelemetry ist für Unternehmen von entscheidender Bedeutung, die bereit sein wollen, zukünftige Datenanforderungen zu erfüllen, ohne an einen bestimmten Anbieter gebunden zu sein oder durch ihre veraltete Technologie eingeschränkt zu sein.

Verfolgen

Die Ablaufverfolgung bietet ein vollständiges Bild des gesamten Lebenszyklus vom Eingang der Anfrage bis zur Fertigstellung.

Nach Eingang der Anfrage ermöglicht der Dienst die Linkverfolgung anhand von Metainformationen (Kitex) oder HTTP-Header (Hertz). Wenn in den Metainformationen oder im HTTP-Header keine Tracing-Informationen vorhanden sind, wird das neue Link-Tracing automatisch aktiviert. Linkinformationen werden innerhalb des Serviceprozesses über den Kontext weitergegeben.

Zugriffsmethode:

// for Hertz
tracer, cfg := hertztracing.NewServerTracer()
h := server.Default(tracer)
h.Use(hertztracing.ServerMiddleware(cfg))
Kopieren
// for Kitex
svr := echo.NewServer(new(DemoImpl),
    server.WithSuite(tracing.NewServerSuite()),
    server.WithServerBasicInfo(&rpcinfo.EndpointBasicInfo{ServiceName: serviceName}),)
Kopieren

Verfolgungsinformationen werden an OpenTelemetry Collector gemeldet und dann transparent an Jaeger übermittelt. Linkbezogene Informationen können in Jaeger abgefragt werden.

Stellt einen einheitlichen Protokolldrucker fzlog bereit, der standardmäßig verfolgungsbezogene Informationen druckt.

{
  "file": "get_repositories.go:33",
  "func": "gitlab.fzzqft.com/ifte-quark/quark-api/biz/service.(*GetRepositoriesService).Run",
  "level": "info",
  "msg": "GetRepositoriesService Run req: page:1 limit:10 service_name:\"kitex\"",
  "span_id": "aa26bab58cdf6806",
  "time": "2024-04-23 15:59:40.609",
  "trace_flags": "01",
  "trace_id": "f714dbe2a96b1882dfc4b81909e55643"
}
Kopieren

Nachdem die Protokolle gesammelt und verarbeitet wurden, können die relevanten Protokollinformationen des gesamten Links auf der Protokollplattform abgefragt werden . trace_id 

Metriken

Metriken sind Schlüsseldaten, die die Systemleistung und das Systemverhalten messen, wie z. B. Anfragerate, Antwortzeit, Fehlerrate usw. Metriken werden in der Regel gesammelt, aggregiert und visualisiert, um den Systemzustand zu überwachen und Trendanalysen durchzuführen.

Derzeit meldet jeder Dienst seine eigenen Metrikdaten, speichert diese einheitlich in Prometheus/VictoriaMetrics und verwendet schließlich Grafana, um ein Überwachungspanel zu bilden.

Im Folgenden werden drei gängige Dienstbeschreibungsindikatoren verwendet: QPS, Anforderungszeit und Fehlerrate, um zu veranschaulichen, wie die vom Dienst gemeldeten Metrikdaten verwendet werden.

  • QPS: Basierend auf der Definition von QPS müssen wir zur Berechnung von QPS nur die Anzahl der Echtzeitanfragen ermitteln. http_server_duration_count Der Wert in den gemeldeten Daten stimmt mit der Anzahl der Anfragen überein, sodass diese Metrik zur Vervollständigung der Berechnung verwendet werden kann QPS.

    sum(rate(http_server_duration_count{service_name="$service_name"}[$__rate_interval]))
    
    Kopieren

    Im obigen promQL wird die Rate-Funktion verwendet, um die Wachstumsrate einer bestimmten Metrik innerhalb eines bestimmten Zeitraums zu berechnen, und das Endergebnis ist die durchschnittliche Anzahl der Anfragen innerhalb des angegebenen Zeitraums.

  • Anforderungszeitverbrauch: Da es sich um statistische Daten handelt, verwenden wir hier den Durchschnitt, um den Zeitverbrauch von Serviceanforderungen darzustellen. Der durchschnittliche Zeitverbrauch wird durch den gesamten Zeitverbrauch aller Anforderungen im angegebenen Zeitraum ermittelt Anfragen im angegebenen Zeitraum:

    sum(rate(http_server_duration_sum{service_name="$service_name"}[$__rate_interval])) by (application) /
    sum(rate(http_server_duration_count{service_name="$service_name"}[$__rate_interval])) by (application)
    
    Kopieren
  • Fehlerrate: Filtern Sie zunächst die Anzahl der fehlerhaften Anfragen heraus und dividieren Sie sie durch die Gesamtzahl der Anfragen, um die Fehlerrate zu erhalten

    round((1 - (sum(rate(http_server_duration_count{service_name="$service_name",http_status_code=~"^(2|3).*"}
    [$__interval]))/sum(rate(http_server_duration_count{service_name="$service_name"}[$__interval])))), 0.0001)
    
    Kopieren

Topologie

Die gesamten Abhängigkeiten zwischen den Diensten werden durch die in der Aggregation genannten Metrikdaten angezeigt. Die gemeldeten Daten enthalten service_nameInformationen sourceund die Upstream- und Downstream-Informationen des Dienstes können targetüber den PromSQL- Operator abgerufen werden.sum

Aufbau von Fähigkeiten zur Verwaltung von Microservice-Schnittstellen

Konzept

  • IDL

    Interface Description Language (IDL) ist eine Computersprache, die zur Beschreibung der Schnittstelle von Softwarekomponenten verwendet wird. IDL beschreibt Schnittstellen auf programmiersprachenunabhängige Weise und ermöglicht es Objekten, die auf verschiedenen Plattformen laufen, und Programmen, die in verschiedenen Sprachen geschrieben sind, miteinander zu kommunizieren.

  • Schnittstellenmanagement

    Kitex (RPC)-Dienste werden alle auf Basis von IDL implementiert. Die Schnittstellenverwaltungsplattform bietet hauptsächlich eine Schnittstellenplattform zur Verwaltung der IDL-Produkte von RPC-Diensten, wodurch es für Entwickler einfacher wird, RPC-Schnittstellen zu verwalten und aufzurufen.

  • Schnittstellentests

    Der Kitex-Dienst (RPC) ist zum Testen nicht erreichbar. Benutzer der Schnittstellentestplattform lösen dieses Problem, um Tests und Entwicklung zu erleichtern, indem sie RPC-Anfragen über die Plattform initiieren, um das Debuggen abzuschließen.

einführen

  • Schnittstellenverwaltungsplattform (Betriebsmethode siehe Bild) huaxing_interface_1 huaxing_interface_2 huaxing_interface_3
  • Schnittstellentestplattform (Debugging der Kitex (RPC)-Schnittstelle) huaxing_interface_test

Umsetzungsprinzipien und Details

  • Schnittstellenmanagement

    Zuvor nutzten wir ein unabhängiges Lager mit gitlabci, um die IDL-Produkte des Kitex- Dienstes zu verwalten: Während der tatsächlichen Nutzung gab es die folgenden Schwachstellen:   huaxing_interface_impl 

    1. Der Anrufer muss über ein kleines Fenster (privater Chat) die Adresse, Filiale oder Versionsnummer des IDL-Produktlagers erhalten.
    2. Bei der Servicebereitstellungsmethode müssen sowohl das Serviceprojektlager als auch das entsprechende Produktlager berücksichtigt werden.
    3. Gitlabci ist stark auf Runner angewiesen und neue Gruppen müssen vom Administrator konfiguriert werden, bevor sie verwendet werden können.
    4. Es kann keine tiefe Bindung an den vorhandenen CICD-Prozess hergestellt werden

    Um die oben genannten Probleme und Schwachstellen zu lösen, wurde eine Schnittstellenverwaltungsplattform entworfen und entwickelt. huaxing_interface_platform

    Wenn der Dienst erstellt und verpackt wird, wird der IDL-Produktaktualisierungsprozess ausgelöst. Die Plattform erkennt automatisch den Diensttyp, generiert das entsprechende IDL-Produkt und übermittelt es an das unabhängige Gitlab-Lager. Benutzer können IDL-Produkte auch manuell auf der Plattform erstellen oder aktualisieren. Der Aufrufer muss lediglich den Importpfadbefehl kopieren und ausführen, um die entsprechende Version der Dienstabhängigkeit zu erhalten.

  • Der Schnittstellentest wird basierend auf dem JSON-Mapping-Generalisierungsaufruf von Kitex PB implementiert. Der Benutzer wählt den entsprechenden Dienst und die entsprechende Schnittstelle auf der Plattform aus, und die Plattform analysiert automatisch die entsprechende IDL-Datei und gibt die Standardanforderungsparameter (JSON-Format) an. Nach dem Senden der Anfrage initiiert die Plattform über einen allgemeinen Aufruf eine RPC-Anfrage an den Zieldienst und gibt das Ergebnis zurück. huaxing_interface_test_logic 

Zusammenfassung

Das aktuelle Microservice-System kann bereits die meisten technischen Anforderungen erfüllen, wir planen jedoch, im Rahmen des Cloud-nativen Systems noch weiter zu gehen:

  1. Die Service-Governance basiert auf Cloud-nativen Service-Mesh-Funktionen (ServiceMesh) zur Verwaltung des Datenverkehrs und integriert gleichzeitig Ost-West-Datenverkehr aus anderen Anwendungs-Frameworks.
  2. Observability, OpenTelemetry ist eine Reihe von Lösungen, die unabhängig von Sprache und Anwendungsframework sind. Durch eine einheitliche Semantik ist geplant, Javas Web- (Springboot) und RPC-Systeme (Dubbo) zusammenzuführen.
  3. Schnittstellenmanagement, in Zukunft ist geplant, RPC- und HTTP-Schnittstellen einheitlich zu verwalten und Schnittstellen-Anwendungsfälle automatisch zu generieren.

kürzliche Aktivitäten

Unternehmensanwender und Entwickler sind herzlich eingeladen, am CloudWeGo Technology Salon teilzunehmen. Die Veranstaltung findet am 25. Mai 2024 ( Samstag) in Shanghai statt und lädt technische Kollegen ein, zu diskutieren, wie Unternehmen eine Cloud-native Microservice-Architektur aufbauen können , um die schnelle Iteration und Entwicklung von Produkten im Rahmen der Cloud-nativen xAI zu unterstützen. Scannen Sie den QR-Code auf dem Bild, um sich sofort anzumelden. Wir sehen uns! 

 

Die Raubkopien von „Celebrating More Than Years 2“ wurden auf npm hochgeladen, was dazu führte, dass npmmirror den Unpkg-Dienst einstellen musste und sich gemeinsam mit Hunderten von Menschen in die USA begab Front-End-Visualisierungsbibliothek und Baidus bekanntes Open-Source-Projekt ECharts – „Going to the Sea“ zur Unterstützung Fischbetrüger nutzten TeamViewer, um 3,98 Millionen zu überweisen! Was sollten Remote-Desktop-Anbieter tun? Zhou Hongyi: Für Google bleibt nicht mehr viel Zeit. Es wird empfohlen, dass alle Produkte Open Source sind. Ein ehemaliger Mitarbeiter eines bekannten Open-Source-Unternehmens brachte die Nachricht: Nachdem er von seinen Untergebenen herausgefordert wurde, wurde der technische Leiter wütend hat die schwangere Mitarbeiterin entlassen. Google hat gezeigt, wie man ChromeOS in einer virtuellen Android-Maschine ausführt. Bitte geben Sie mir einen Rat, welche Rolle time.sleep(6) hier spielt. Microsoft reagiert auf Gerüchte, dass Chinas KI-Team „für die USA packt“. People's Daily Online kommentiert die matroschkaartige Aufladung von Bürosoftware: Nur durch das aktive Lösen von „Sets“ können wir eine Zukunft haben
{{o.name}}
{{m.name}}

Ich denke du magst

Origin my.oschina.net/u/4843764/blog/11181511
Empfohlen
Rangfolge