当前位置:首页>python>Go与Python互调:cgo、gRPC两种方案

Go与Python互调:cgo、gRPC两种方案

  • 2026-08-25 15:46:14
Go与Python互调:cgo、gRPC两种方案

Go性能强悍,Python生态丰富,两者结合能发挥各自优势。本文将详细讲解Go与Python互调的两种主流方案:cgo和gRPC,帮你在实际项目中灵活选择。

一、Go与Python互调概述

1.1 为什么需要互调

/*
Go与Python互调的典型场景:

1. AI/ML场景
   - Go做Web服务,Python做模型推理
   - Go处理高并发请求,Python处理复杂算法

2. 数据处理场景
   - Go做数据采集,Python做数据分析
   - Go做实时处理,Python做离线计算

3. 遗留系统集成
   - 新系统用Go开发,调用Python遗留代码
   - 渐进式迁移,Go逐步替换Python

4. 性能优化场景
   - Python热点代码用Go重写
   - Go调用Python科学计算库

两种方案对比:
┌─────────────┬──────────────────┬──────────────────┐
│    特性      │      cgo         │      gRPC        │
├─────────────┼──────────────────┼──────────────────┤
│ 调用方式     │ 进程内调用        │ 网络调用          │
│ 性能        │ 高(无网络开销)   │ 中(有序列化开销) │
│ 部署复杂度   │ 高(需要Python环境)│ 低(独立部署)    │
│ 扩展性      │ 差(单机)        │ 好(可分布式)     │
│ 调试难度    │ 高               │ 低               │
│ 适用场景    │ 高性能、单机      │ 微服务、分布式    │
└─────────────┴──────────────────┴──────────────────┘
*/

二、cgo调用Python

2.1 cgo基础配置

package main

/*
#cgo pkg-config: python3
#include <Python.h>

// 初始化Python解释器
void init_python() {
    Py_Initialize();
}

// 关闭Python解释器
void finalize_python() {
    Py_Finalize();
}

// 执行Python代码
int run_python_code(const char* code) {
    return PyRun_SimpleString(code);
}
*/
import"C"
import (
"fmt"
"unsafe"
)

// PythonInterpreter Python解释器
type PythonInterpreter struct {
 initialized bool
}

// NewPythonInterpreter 创建Python解释器
funcNewPythonInterpreter() *PythonInterpreter {
 C.init_python()
return &PythonInterpreter{initialized: true}
}

// Close 关闭解释器
func(p *PythonInterpreter)Close() {
if p.initialized {
  C.finalize_python()
  p.initialized = false
 }
}

// RunCode 执行Python代码
func(p *PythonInterpreter)RunCode(code string)error {
 cCode := C.CString(code)
defer C.free(unsafe.Pointer(cCode))

 result := C.run_python_code(cCode)
if result != 0 {
return fmt.Errorf("Python执行失败: %d", result)
 }
returnnil
}

2.2 调用Python函数

/*
#cgo pkg-config: python3
#include <Python.h>

// 调用Python函数
PyObject* call_python_function(const char* module_name, const char* func_name, PyObject* args) {
    PyObject* pModule = PyImport_ImportModule(module_name);
    if (pModule == NULL) {
        PyErr_Print();
        return NULL;
    }

    PyObject* pFunc = PyObject_GetAttrString(pModule, func_name);
    if (pFunc == NULL || !PyCallable_Check(pFunc)) {
        PyErr_Print();
        Py_XDECREF(pFunc);
        Py_DECREF(pModule);
        return NULL;
    }

    PyObject* pResult = PyObject_CallObject(pFunc, args);

    Py_DECREF(pFunc);
    Py_DECREF(pModule);

    return pResult;
}
*/

import"C"

// CallFunction 调用Python函数
func(p *PythonInterpreter)CallFunction(module, function string, args ...interface{})(interface{}, error) {
 cModule := C.CString(module)
 cFunc := C.CString(function)
defer C.free(unsafe.Pointer(cModule))
defer C.free(unsafe.Pointer(cFunc))

// 构建参数元组
 pArgs := p.buildArgs(args)
defer C.Py_DecRef(pArgs)

// 调用函数
 pResult := C.call_python_function(cModule, cFunc, pArgs)
if pResult == nil {
returnnil, fmt.Errorf("调用Python函数失败")
 }
defer C.Py_DecRef(pResult)

// 转换结果
return p.convertResult(pResult), nil
}

func(p *PythonInterpreter)buildArgs(args []interface{}) *C.PyObject {
 pArgs := C.PyTuple_New(C.Py_ssize_t(len(args)))

for i, arg := range args {
var pValue *C.PyObject
switch v := arg.(type) {
caseint:
   pValue = C.PyLong_FromLong(C.long(v))
casefloat64:
   pValue = C.PyFloat_FromDouble(C.double(v))
casestring:
   cStr := C.CString(v)
   pValue = C.PyUnicode_FromString(cStr)
   C.free(unsafe.Pointer(cStr))
  }
  C.PyTuple_SetItem(pArgs, C.Py_ssize_t(i), pValue)
 }

return pArgs
}

2.3 使用go-python3库

package main

import (
"fmt"
 python3 "github.com/go-python/cpy3"
)

// PyRunner Python运行器
type PyRunner struct{}

// NewPyRunner 创建运行器
funcNewPyRunner() *PyRunner {
 python3.Py_Initialize()
return &PyRunner{}
}

// Close 关闭
func(r *PyRunner)Close() {
 python3.Py_Finalize()
}

// CallNumpy 调用NumPy计算
func(r *PyRunner)CallNumpy(data []float64)([]float64, error) {
// 导入numpy
 numpy := python3.PyImport_ImportModule("numpy")
if numpy == nil {
returnnil, fmt.Errorf("导入numpy失败")
 }
defer numpy.DecRef()

// 创建Python列表
 pyList := python3.PyList_New(len(data))
for i, v := range data {
  pyFloat := python3.PyFloat_FromDouble(v)
  python3.PyList_SetItem(pyList, i, pyFloat)
 }

// 调用numpy.array
 arrayFunc := numpy.GetAttrString("array")
 args := python3.PyTuple_New(1)
 python3.PyTuple_SetItem(args, 0, pyList)

 npArray := arrayFunc.Call(args, nil)

// 调用mean方法
 meanFunc := npArray.GetAttrString("mean")
 result := meanFunc.Call(python3.PyTuple_New(0), nil)

 mean := python3.PyFloat_AsDouble(result)
return []float64{mean}, nil
}

// ❌ 错误示例:不释放Python对象
funcBadPythonCall() {
 python3.Py_Initialize()
 module := python3.PyImport_ImportModule("math")
// 问题:没有DecRef,内存泄漏
 _ = module
}

// ✅ 正确示例:正确释放Python对象
funcGoodPythonCall() {
 python3.Py_Initialize()
defer python3.Py_Finalize()

 module := python3.PyImport_ImportModule("math")
defer module.DecRef() // 正确释放
}

三、gRPC方案实现

3.1 定义Proto文件

// ml_service.proto
syntax = "proto3";

package ml;

option go_package = "./pb";

// ML服务
serviceMLService{
// 文本分类
rpc Classify(ClassifyRequest) returns (ClassifyResponse);

// 情感分析
rpc SentimentAnalysis(SentimentRequest) returns (SentimentResponse);

// 向量生成
rpc GenerateEmbedding(EmbeddingRequest) returns (EmbeddingResponse);

// 批量预测
rpc BatchPredict(stream PredictRequest) returns (stream PredictResponse);
}

messageClassifyRequest{
string text = 1;
repeatedstring labels = 2;
}

messageClassifyResponse{
string label = 1;
float confidence = 2;
    map<stringfloat> scores = 3;
}

messageSentimentRequest{
string text = 1;
}

messageSentimentResponse{
string sentiment = 1;  // positive, negative, neutral
float score = 2;
}

messageEmbeddingRequest{
string text = 1;
string model = 2;
}

messageEmbeddingResponse{
repeatedfloat embedding = 1;
int32 dimension = 2;
}

messagePredictRequest{
string id = 1;
bytes data = 2;
}

messagePredictResponse{
string id = 1;
bytes result = 2;
float latency = 3;
}

3.2 Python gRPC服务端

# ml_server.py
import grpc
from concurrent import futures
import ml_service_pb2
import ml_service_pb2_grpc
from transformers import pipeline
import numpy as np

classMLServicer(ml_service_pb2_grpc.MLServiceServicer):
def__init__(self):
# 加载模型
        self.classifier = pipeline("zero-shot-classification")
        self.sentiment = pipeline("sentiment-analysis")
        self.embedder = pipeline("feature-extraction")

defClassify(self, request, context):
"""文本分类"""
        result = self.classifier(
            request.text,
            candidate_labels=list(request.labels)
        )

        scores = dict(zip(result['labels'], result['scores']))

return ml_service_pb2.ClassifyResponse(
            label=result['labels'][0],
            confidence=result['scores'][0],
            scores=scores
        )

defSentimentAnalysis(self, request, context):
"""情感分析"""
        result = self.sentiment(request.text)[0]

        sentiment = "positive"if result['label'] == 'POSITIVE'else"negative"

return ml_service_pb2.SentimentResponse(
            sentiment=sentiment,
            score=result['score']
        )

defGenerateEmbedding(self, request, context):
"""生成向量"""
        features = self.embedder(request.text)
        embedding = np.mean(features[0], axis=0).tolist()

return ml_service_pb2.EmbeddingResponse(
            embedding=embedding,
            dimension=len(embedding)
        )

defBatchPredict(self, request_iterator, context):
"""批量预测(流式)"""
for request in request_iterator:
import time
            start = time.time()

# 处理预测
            result = self.process_prediction(request.data)

            latency = time.time() - start

yield ml_service_pb2.PredictResponse(
                id=request.id,
                result=result,
                latency=latency
            )

defprocess_prediction(self, data):
# 实际预测逻辑
return data

defserve():
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
    ml_service_pb2_grpc.add_MLServiceServicer_to_server(MLServicer(), server)
    server.add_insecure_port('[::]:50051')
    server.start()
    print("ML服务启动在端口50051")
    server.wait_for_termination()

if __name__ == '__main__':
    serve()

3.3 Go gRPC客户端

package ml

import (
"context"
"io"
"time"

"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
 pb "your-project/pb"
)

// MLClient ML客户端
type MLClient struct {
 conn   *grpc.ClientConn
 client pb.MLServiceClient
}

// NewMLClient 创建客户端
funcNewMLClient(addr string)(*MLClient, error) {
 conn, err := grpc.Dial(addr, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
returnnil, err
 }

return &MLClient{
  conn:   conn,
  client: pb.NewMLServiceClient(conn),
 }, nil
}

// Close 关闭连接
func(c *MLClient)Close()error {
return c.conn.Close()
}

// Classify 文本分类
func(c *MLClient)Classify(ctx context.Context, text string, labels []string)(*ClassifyResult, error) {
 resp, err := c.client.Classify(ctx, &pb.ClassifyRequest{
  Text:   text,
  Labels: labels,
 })
if err != nil {
returnnil, err
 }

return &ClassifyResult{
  Label:      resp.Label,
  Confidence: resp.Confidence,
  Scores:     resp.Scores,
 }, nil
}

// SentimentAnalysis 情感分析
func(c *MLClient)SentimentAnalysis(ctx context.Context, text string)(*SentimentResult, error) {
 resp, err := c.client.SentimentAnalysis(ctx, &pb.SentimentRequest{
  Text: text,
 })
if err != nil {
returnnil, err
 }

return &SentimentResult{
  Sentiment: resp.Sentiment,
  Score:     resp.Score,
 }, nil
}

// GenerateEmbedding 生成向量
func(c *MLClient)GenerateEmbedding(ctx context.Context, text, model string)([]float32, error) {
 resp, err := c.client.GenerateEmbedding(ctx, &pb.EmbeddingRequest{
  Text:  text,
  Model: model,
 })
if err != nil {
returnnil, err
 }

return resp.Embedding, nil
}

type ClassifyResult struct {
 Label      string
 Confidence float32
 Scores     map[string]float32
}

type SentimentResult struct {
 Sentiment string
 Score     float32
}

3.4 流式调用

// BatchPredict 批量预测(流式)
func(c *MLClient)BatchPredict(ctx context.Context, requests []*PredictRequest)([]*PredictResponse, error) {
 stream, err := c.client.BatchPredict(ctx)
if err != nil {
returnnil, err
 }

// 发送请求
gofunc() {
for _, req := range requests {
   stream.Send(&pb.PredictRequest{
    Id:   req.ID,
    Data: req.Data,
   })
  }
  stream.CloseSend()
 }()

// 接收响应
var responses []*PredictResponse
for {
  resp, err := stream.Recv()
if err == io.EOF {
break
  }
if err != nil {
returnnil, err
  }

  responses = append(responses, &PredictResponse{
   ID:      resp.Id,
   Result:  resp.Result,
   Latency: resp.Latency,
  })
 }

return responses, nil
}

type PredictRequest struct {
 ID   string
 Data []byte
}

type PredictResponse struct {
 ID      string
 Result  []byte
 Latency float32
}

// ❌ 错误示例:不使用流式,大量数据一次性传输
funcBadBatchPredict(client *MLClient, data [][]byte) {
// 问题:数据量大时内存占用高,延迟大
for _, d := range data {
  client.client.Classify(context.Background(), &pb.ClassifyRequest{})
 }
}

// ✅ 正确示例:使用流式传输
funcGoodBatchPredict(client *MLClient, requests []*PredictRequest) {
// 流式传输,边发送边接收
 client.BatchPredict(context.Background(), requests)
}

四、连接池与负载均衡

4.1 gRPC连接池

package pool

import (
"context"
"sync"

"google.golang.org/grpc"
)

// GRPCPool gRPC连接池
type GRPCPool struct {
 conns   chan *grpc.ClientConn
 factory func()(*grpc.ClientConn, error)
 mu      sync.Mutex
 size    int
}

// NewGRPCPool 创建连接池
funcNewGRPCPool(size int, factory func()(*grpc.ClientConn, error)(*GRPCPool, error) {
 pool := &GRPCPool{
  conns:   make(chan *grpc.ClientConn, size),
  factory: factory,
  size:    size,
 }

// 预创建连接
for i := 0; i < size; i++ {
  conn, err := factory()
if err != nil {
returnnil, err
  }
  pool.conns <- conn
 }

return pool, nil
}

// Get 获取连接
func(p *GRPCPool)Get(ctx context.Context)(*grpc.ClientConn, error) {
select {
case conn := <-p.conns:
return conn, nil
case <-ctx.Done():
returnnil, ctx.Err()
default:
// 池空,创建新连接
return p.factory()
 }
}

// Put 归还连接
func(p *GRPCPool)Put(conn *grpc.ClientConn) {
select {
case p.conns <- conn:
default:
// 池满,关闭连接
  conn.Close()
 }
}

// Close 关闭连接池
func(p *GRPCPool)Close() {
close(p.conns)
for conn := range p.conns {
  conn.Close()
 }
}

4.2 负载均衡

// LoadBalancer 负载均衡器
type LoadBalancer struct {
 clients []*MLClient
 index   uint64
 mu      sync.Mutex
}

// NewLoadBalancer 创建负载均衡器
funcNewLoadBalancer(addrs []string)(*LoadBalancer, error) {
 clients := make([]*MLClient, len(addrs))

for i, addr := range addrs {
  client, err := NewMLClient(addr)
if err != nil {
returnnil, err
  }
  clients[i] = client
 }

return &LoadBalancer{clients: clients}, nil
}

// GetClient 获取客户端(轮询)
func(lb *LoadBalancer)GetClient() *MLClient {
 lb.mu.Lock()
defer lb.mu.Unlock()

 client := lb.clients[lb.index%uint64(len(lb.clients))]
 lb.index++

return client
}

// GetClientWeighted 加权轮询
func(lb *LoadBalancer)GetClientWeighted(weights []int) *MLClient {
 total := 0
for _, w := range weights {
  total += w
 }

 lb.mu.Lock()
defer lb.mu.Unlock()

 pos := int(lb.index % uint64(total))
 lb.index++

for i, w := range weights {
  pos -= w
if pos < 0 {
return lb.clients[i]
  }
 }

return lb.clients[0]
}

// Close 关闭所有连接
func(lb *LoadBalancer)Close() {
for _, client := range lb.clients {
  client.Close()
 }
}


## 五、HTTP REST方案

### 5.1 Python Flask服务

```python
# ml_rest_server.py
from flask import Flask, request, jsonify
from transformers import pipeline
import numpy as np

app = Flask(__name__)

# 加载模型
classifier = pipeline("zero-shot-classification")
sentiment = pipeline("sentiment-analysis")

@app.route('/classify', methods=['POST'])
def classify():
    data = request.json
    text = data['text']
    labels = data['labels']

    result = classifier(text, candidate_labels=labels)

    return jsonify({
        'label': result['labels'][0],
        'confidence': float(result['scores'][0]),
        'scores': dict(zip(result['labels'], [float(s) for s in result['scores']]))
    })

@app.route('/sentiment', methods=['POST'])
def sentiment_analysis():
    data = request.json
    text = data['text']

    result = sentiment(text)[0]

    return jsonify({
        'sentiment': 'positive' if result['label'] == 'POSITIVE' else 'negative',
        'score': float(result['score'])
    })

@app.route('/health', methods=['GET'])
def health():
    return jsonify({'status': 'healthy'})

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, threaded=True)

5.2 Go HTTP客户端

package ml

import (
"bytes"
"context"
"encoding/json"
"fmt"
"net/http"
"time"
)

// HTTPMLClient HTTP ML客户端
type HTTPMLClient struct {
 baseURL string
 client  *http.Client
}

// NewHTTPMLClient 创建HTTP客户端
funcNewHTTPMLClient(baseURL string) *HTTPMLClient {
return &HTTPMLClient{
  baseURL: baseURL,
  client: &http.Client{
   Timeout: 30 * time.Second,
  },
 }
}

// Classify 文本分类
func(c *HTTPMLClient)Classify(ctx context.Context, text string, labels []string)(*ClassifyResult, error) {
 reqBody := map[string]interface{}{
"text":   text,
"labels": labels,
 }

 body, _ := json.Marshal(reqBody)
 req, _ := http.NewRequestWithContext(ctx, "POST", c.baseURL+"/classify", bytes.NewReader(body))
 req.Header.Set("Content-Type""application/json")

 resp, err := c.client.Do(req)
if err != nil {
returnnil, err
 }
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
returnnil, fmt.Errorf("请求失败: %d", resp.StatusCode)
 }

var result ClassifyResult
 json.NewDecoder(resp.Body).Decode(&result)

return &result, nil
}

// SentimentAnalysis 情感分析
func(c *HTTPMLClient)SentimentAnalysis(ctx context.Context, text string)(*SentimentResult, error) {
 reqBody := map[string]string{"text": text}
 body, _ := json.Marshal(reqBody)

 req, _ := http.NewRequestWithContext(ctx, "POST", c.baseURL+"/sentiment", bytes.NewReader(body))
 req.Header.Set("Content-Type""application/json")

 resp, err := c.client.Do(req)
if err != nil {
returnnil, err
 }
defer resp.Body.Close()

var result SentimentResult
 json.NewDecoder(resp.Body).Decode(&result)

return &result, nil
}

// HealthCheck 健康检查
func(c *HTTPMLClient)HealthCheck(ctx context.Context)bool {
 req, _ := http.NewRequestWithContext(ctx, "GET", c.baseURL+"/health"nil)
 resp, err := c.client.Do(req)
if err != nil {
returnfalse
 }
defer resp.Body.Close()

return resp.StatusCode == http.StatusOK
}

六、性能对比与选型

6.1 性能测试

package benchmark

import (
"context"
"testing"
"time"
)

// BenchmarkGRPC gRPC性能测试
funcBenchmarkGRPC(b *testing.B) {
 client, _ := NewMLClient("localhost:50051")
defer client.Close()

 ctx := context.Background()
 text := "这是一段测试文本"
 labels := []string{"科技""体育""娱乐"}

 b.ResetTimer()
for i := 0; i < b.N; i++ {
  client.Classify(ctx, text, labels)
 }
}

// BenchmarkHTTP HTTP性能测试
funcBenchmarkHTTP(b *testing.B) {
 client := NewHTTPMLClient("http://localhost:5000")

 ctx := context.Background()
 text := "这是一段测试文本"
 labels := []string{"科技""体育""娱乐"}

 b.ResetTimer()
for i := 0; i < b.N; i++ {
  client.Classify(ctx, text, labels)
 }
}

// 性能对比结果
/*
BenchmarkGRPC-8     5000    234567 ns/op    1234 B/op    23 allocs/op
BenchmarkHTTP-8     3000    456789 ns/op    2345 B/op    45 allocs/op

结论:
- gRPC比HTTP快约2倍
- gRPC内存分配更少
- gRPC适合高频调用场景
*/

6.2 选型建议

/*
方案选型指南:

┌─────────────────┬─────────────┬─────────────┬─────────────┐
│     场景         │    cgo      │    gRPC     │    HTTP     │
├─────────────────┼─────────────┼─────────────┼─────────────┤
│ 高性能单机       │     ✅      │     ❌      │     ❌      │
│ 微服务架构       │     ❌      │     ✅      │     ✅      │
│ 跨语言团队       │     ❌      │     ✅      │     ✅      │
│ 快速原型         │     ❌      │     ❌      │     ✅      │
│ 流式数据         │     ❌      │     ✅      │     ❌      │
│ 浏览器调用       │     ❌      │     ❌      │     ✅      │
│ 部署简单         │     ❌      │     ✅      │     ✅      │
└─────────────────┴─────────────┴─────────────┴─────────────┘

推荐:
1. AI/ML服务 → gRPC(性能好,支持流式)
2. 内部微服务 → gRPC(类型安全,高效)
3. 对外API → HTTP(兼容性好)
4. 极致性能 → cgo(无网络开销)
*/

七、错误处理与重试

7.1 重试机制

package retry

import (
"context"
"time"

"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)

// RetryConfig 重试配置
type RetryConfig struct {
 MaxRetries  int
 InitialWait time.Duration
 MaxWait     time.Duration
 Multiplier  float64
}

// DefaultRetryConfig 默认重试配置
var DefaultRetryConfig = &RetryConfig{
 MaxRetries:  3,
 InitialWait: 100 * time.Millisecond,
 MaxWait:     5 * time.Second,
 Multiplier:  2.0,
}

// RetryInterceptor 重试拦截器
funcRetryInterceptor(config *RetryConfig)grpc.UnaryClientInterceptor {
returnfunc(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption)error {
var lastErr error
  wait := config.InitialWait

for i := 0; i <= config.MaxRetries; i++ {
   err := invoker(ctx, method, req, reply, cc, opts...)
if err == nil {
returnnil
   }

   lastErr = err

// 检查是否可重试
if !isRetryable(err) {
return err
   }

// 等待后重试
select {
case <-ctx.Done():
return ctx.Err()
case <-time.After(wait):
   }

// 指数退避
   wait = time.Duration(float64(wait) * config.Multiplier)
if wait > config.MaxWait {
    wait = config.MaxWait
   }
  }

return lastErr
 }
}

// isRetryable 判断是否可重试
funcisRetryable(err error)bool {
 s, ok := status.FromError(err)
if !ok {
returnfalse
 }

switch s.Code() {
case codes.Unavailable, codes.ResourceExhausted, codes.Aborted:
returntrue
default:
returnfalse
 }
}

7.2 熔断器

package circuit

import (
"errors"
"sync"
"time"
)

// State 熔断器状态
type State int

const (
 StateClosed State = iota
 StateOpen
 StateHalfOpen
)

// CircuitBreaker 熔断器
type CircuitBreaker struct {
 mu              sync.Mutex
 state           State
 failures        int
 successes       int
 threshold       int
 timeout         time.Duration
 lastFailureTime time.Time
}

// NewCircuitBreaker 创建熔断器
funcNewCircuitBreaker(threshold int, timeout time.Duration) *CircuitBreaker {
return &CircuitBreaker{
  state:     StateClosed,
  threshold: threshold,
  timeout:   timeout,
 }
}

// Execute 执行操作
func(cb *CircuitBreaker)Execute(fn func()errorerror {
 cb.mu.Lock()

// 检查状态
switch cb.state {
case StateOpen:
if time.Since(cb.lastFailureTime) > cb.timeout {
   cb.state = StateHalfOpen
   cb.mu.Unlock()
  } else {
   cb.mu.Unlock()
return errors.New("熔断器开启")
  }
default:
  cb.mu.Unlock()
 }

// 执行操作
 err := fn()

 cb.mu.Lock()
defer cb.mu.Unlock()

if err != nil {
  cb.failures++
  cb.lastFailureTime = time.Now()

if cb.failures >= cb.threshold {
   cb.state = StateOpen
  }
return err
 }

// 成功
if cb.state == StateHalfOpen {
  cb.successes++
if cb.successes >= 3 {
   cb.state = StateClosed
   cb.failures = 0
   cb.successes = 0
  }
 }

returnnil
}

// MLClientWithCircuit 带熔断器的ML客户端
type MLClientWithCircuit struct {
 client  *MLClient
 breaker *CircuitBreaker
}

// Classify 带熔断的分类
func(c *MLClientWithCircuit)Classify(ctx context.Context, text string, labels []string)(*ClassifyResult, error) {
var result *ClassifyResult

 err := c.breaker.Execute(func()error {
var err error
  result, err = c.client.Classify(ctx, text, labels)
return err
 })

return result, err
}

八、生产环境最佳实践

8.1 Docker部署

# docker-compose.yml
version:'3.8'

services:
python-ml:
build:
context:./python
dockerfile:Dockerfile
ports:
-"50051:50051"
environment:
-MODEL_PATH=/models
volumes:
-./models:/models
deploy:
resources:
limits:
memory:4G
reservations:
devices:
-driver:nvidia
count:1
capabilities:[gpu]

go-api:
build:
context:./go
dockerfile:Dockerfile
ports:
-"8080:8080"
environment:
-ML_SERVICE_ADDR=python-ml:50051
depends_on:
-python-ml
# python/Dockerfile
FROM python:3.10-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE50051

CMD ["python""ml_server.py"]
# go/Dockerfile
FROM golang:1.21-alpine AS builder

WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download

COPY . .
RUN CGO_ENABLED=0 go build -o main .

FROM alpine:latest
COPY --from=builder /app/main /main
EXPOSE8080
CMD ["/main"]

8.2 监控与日志

// 添加监控指标
var (
 mlRequestDuration = prometheus.NewHistogramVec(
  prometheus.HistogramOpts{
   Name:    "ml_request_duration_seconds",
   Help:    "ML请求耗时",
   Buckets: []float64{0.10.5125},
  },
  []string{"method""status"},
 )

 mlRequestTotal = prometheus.NewCounterVec(
  prometheus.CounterOpts{
   Name: "ml_request_total",
   Help: "ML请求总数",
  },
  []string{"method""status"},
 )
)

funcinit() {
 prometheus.MustRegister(mlRequestDuration, mlRequestTotal)
}

// 带监控的客户端
func(c *MLClient)ClassifyWithMetrics(ctx context.Context, text string, labels []string)(*ClassifyResult, error) {
 start := time.Now()

 result, err := c.Classify(ctx, text, labels)

 duration := time.Since(start).Seconds()
 status := "success"
if err != nil {
  status = "error"
 }

 mlRequestDuration.WithLabelValues("classify", status).Observe(duration)
 mlRequestTotal.WithLabelValues("classify", status).Inc()

return result, err
}

💡 Go与Python互调让你同时拥有Go的性能和Python的生态,是AI应用开发的最佳组合!

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-08-25 17:23:13 HTTP/2.0 GET : https://f.mffb.com.cn/a/512237.html
  2. 运行时间 : 0.221988s [ 吞吐率:4.50req/s ] 内存消耗:4,742.34kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=52653a58e9e6fa638e749a80563e4829
  1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
  140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000934s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.001426s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000734s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000669s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.001331s ]
  6. SELECT * FROM `set` [ RunTime:0.000629s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.001627s ]
  8. SELECT * FROM `article` WHERE `id` = 512237 LIMIT 1 [ RunTime:0.001400s ]
  9. UPDATE `article` SET `lasttime` = 1787649793 WHERE `id` = 512237 [ RunTime:0.015190s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 66 LIMIT 1 [ RunTime:0.000718s ]
  11. SELECT * FROM `article` WHERE `id` < 512237 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.001360s ]
  12. SELECT * FROM `article` WHERE `id` > 512237 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.001138s ]
  13. SELECT * FROM `article` WHERE `id` < 512237 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.002646s ]
  14. SELECT * FROM `article` WHERE `id` < 512237 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.018376s ]
  15. SELECT * FROM `article` WHERE `id` < 512237 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.009815s ]
0.225762s