golang基于grpc的电商微服务插件库digota的使用

Golang基于gRPC的电商微服务插件库digota的使用

Digota Logo

Digota - 电商微服务

Digota是一个基于gRPC、protocol-buffers和HTTP2构建的电商微服务,旨在成为现代电商系统的标准。它提供干净、强大且安全的RPC接口。

我们的目标是提供覆盖大多数电商流程的最佳技术,让您只需专注于业务逻辑,而无需担心电商逻辑。

简而言之:可扩展的电商微服务。

快速开始

先决条件

  • Go > 1.8
  • 数据库
    • mongodb > 3.2
    • redis (待实现)
    • postgresql (待实现)
  • 锁服务器(默认为内存锁)
    • zookeeper
    • redis (感谢@Gerifield)
    • etcd (待实现)

安装

从源代码安装:

$ go get -u github.com/digota/digota

从Docker Hub安装:

$ docker pull digota/digota:0.1

运行

$ docker run digota/digota:0.1

或带参数运行:

$ docker run digota/digota:0.1 bash -c "digota --version"

核心服务

支付服务

service Payment {
    rpc Charge  (chargeRequest) returns (charge)        {}
    rpc Refund  (refundRequest) returns (charge)        {}
    rpc Get     (getRequest)    returns (charge)        {}
    rpc List    (listRequest)   returns (chargeList)    {}
}

支付服务用于信用卡/借记卡收费和退款,支持多种支付提供商。如果您使用order功能,通常不需要直接使用此服务。

订单服务

service Order {
    rpc New     (newRequest)    returns (order)         {}
    rpc Get     (getRequest)    returns (order)         {}
    rpc Pay     (payRequest)    returns (order)         {}
    rpc Return  (returnRequest) returns (order)         {}
    rpc List    (listRequest)   returns (listResponse)  {}
}

订单服务帮助您处理结构化购买,即订单。订单自然是一组可购买的产品、折扣、发票和基本客户信息。

产品服务

service Product {
    rpc New     (newRequest)    returns (product)       {}
    rpc Get     (getRequest)    returns (product)       {}
    rpc Update  (updateRequest) returns (product)       {}
    rpc Delete  (deleteRequest) returns (empty)         {}
    rpc List    (listRequest)   returns (productList)   {}
}

产品服务帮助您管理产品,产品代表可购买项(SKU)的集合,无论是实物还是数字产品。

SKU服务

service Sku {
    rpc New     (newRequest)    returns (sku)           {}
    rpc Get     (getRequest)    returns (sku)           {}
    rpc Update  (updateRequest) returns (sku)           {}
    rpc Delete  (deleteRequest) returns (empty)         {}
    rpc List    (listRequest)   returns (skuList)       {}
}

SKU服务帮助您管理产品库存单位(SKU),SKU代表特定的产品配置,如属性、货币和价格。

使用示例

创建新订单

order.New(context.Background(), &orderpb.NewRequest{
    Currency: paymentpb.Currency_EUR,
    Items: []*orderpb.OrderItem{
    	{
    		Parent:   "af350ecc-56c8-485f-8858-74d4faffa9cb",
    		Quantity: 2,
    		Type:     orderpb.OrderItem_sku,
    	},
    	{
    		Amount:      -1000,
    		Description: "Discount for being loyal customer",
    		Currency:    paymentpb.Currency_EUR,
    		Type:        orderpb.OrderItem_discount,
    	},
    	{
    		Amount:      1000,
    		Description: "Tax",
    		Currency:    paymentpb.Currency_EUR,
    		Type:        orderpb.OrderItem_tax,
    	},
    },
    Email: "yaron@digota.com",
    Shipping: &orderpb.Shipping{
    	Name:  "Yaron Sumel",
    	Phone: "+972 000 000 000",
    	Address: &orderpb.Shipping_Address{
    		Line1:      "Loren ipsum",
    		City:       "San Jose",
    		Country:    "USA",
    		Line2:      "",
    		PostalCode: "12345",
    		State:      "CA",
    	},
    },
})

支付订单

order.Pay(context.Background(), &orderpb.PayRequest{
    Id:                "bf350ecc-56c8-485f-8858-74d4faffa9cb",
    PaymentProviderId: paymentpb.PaymentProviderId_Stripe,
    Card: &paymentpb.Card{
        Type:        paymentpb.CardType_Visa,
    	CVC:         "123",
    	ExpireMonth: "12",
    	ExpireYear:  "2022",
    	LastName:    "Sumel",
    	FirstName:   "Yaron",
    	Number:      "4242424242424242",
    },
})			

授权与安全

我们非常重视安全性,请不要犹豫报告安全问题。

Digota使用TLS完全加密(端到端),这一事实也被用来基于客户端证书在本地证书颁发机构前进行认证。

创建CA

$ certstrap init --common-name "ca.company.com"

创建客户端证书

$ certstrap request-cert --domain client.company.com

签署证书

$ certstrap sign --CA "ca.company.com" client.company.com

批准证书

获取证书序列号并将序列号和范围(WRITE,READ,WILDCARD)添加到您的配置中

$ openssl x509 -in out/client.com.crt -serial | grep -Po '(?<=serial=)\w+'
output: A2FF9503829A3A0DDE9CB87191A472D4

货币处理

在处理货币时,浮点数很棘手,我们不想损失金钱,因此这里选择的货币表示基于最小货币单位。例如:4726表示$47.26

分布式锁

所有重要的数据使用都是"独占保证"的,这意味着您无需担心不同节点之间的任何并发数据竞争。典型的数据访问如下:

Client #1 GetSomething -> TryLock -> [lock accuired] ->  DoSomething -> ReleaseLock -> Return Something 
                                                                                 \ 
Client #2 GetSomething -> TryLock -> --------- [wait for lock] -------------------*-----> [lock accuired] -> ...
                                         
Client #3 GetSomething -> TryLock -> -------------------- [wait for lock] ---> [accuire error] -> Return Error

许可证

// Digota <http://digota.com> - eCommerce microservice
// Copyright (c) 2018 Yaron Sumel <yaron@digota.com>
//
// MIT License
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

联系

如有任何问题或咨询,请联系yaron@digota.com


更多关于golang基于grpc的电商微服务插件库digota的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang基于grpc的电商微服务插件库digota的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Digota: 基于gRPC的电商微服务插件库

Digota是一个基于gRPC的电商微服务框架,它提供了一套完整的电商系统基础组件,包括订单、支付、库存等核心功能模块。下面我将详细介绍Digota的使用方法,并提供一些Golang代码示例。

Digota核心特性

  1. 基于gRPC的微服务架构
  2. 内置支付处理(支持Stripe等支付网关)
  3. 订单管理系统
  4. 库存管理
  5. 用户认证和授权
  6. 可扩展的插件架构

安装Digota

go get github.com/digota/digota

基本使用示例

1. 启动Digota服务

package main

import (
	"log"
	"net"
	
	"github.com/digota/digota/config"
	"github.com/digota/digota/server"
	"google.golang.org/grpc"
)

func main() {
	// 加载配置
	conf := &config.Config{
		PaymentProviders: []config.PaymentProvider{
			{
				Provider: "stripe",
				Secret:  "your_stripe_secret_key",
			},
		},
		Database: config.Database{
			Address:  []string{"localhost:27017"},
			Database: "digota",
			Username: "",
			Password: "",
		},
	}
	
	// 初始化服务
	if err := server.Init(conf); err != nil {
		log.Fatal(err)
	}
	
	// 创建gRPC服务器
	s := grpc.NewServer()
	
	// 注册服务
	server.RegisterServices(s)
	
	// 启动监听
	lis, err := net.Listen("tcp", ":8080")
	if err != nil {
		log.Fatal(err)
	}
	
	log.Println("Server started on :8080")
	if err := s.Serve(lis); err != nil {
		log.Fatal(err)
	}
}

2. 创建订单

package main

import (
	"context"
	"log"
	
	"github.com/digota/digota/order/orderpb"
	"github.com/digota/digota/payment/paymentpb"
	"google.golang.org/grpc"
)

func main() {
	// 连接gRPC服务器
	conn, err := grpc.Dial("localhost:8080", grpc.WithInsecure())
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()
	
	// 创建订单客户端
	client := orderpb.NewOrderServiceClient(conn)
	
	// 创建订单请求
	req := &orderpb.NewRequest{
		Currency: orderpb.Currency_USD,
		Items: []*orderpb.OrderItem{
			{
				Parent:     "product_123",
				Quantity:   2,
				Price:      1000, // 10.00美元
				Currency:   orderpb.Currency_USD,
			},
		},
		Email: "customer@example.com",
		PaymentProvider: paymentpb.PaymentProvider_Stripe,
	}
	
	// 调用创建订单方法
	order, err := client.New(context.Background(), req)
	if err != nil {
		log.Fatal(err)
	}
	
	log.Printf("Created order: %v", order)
}

3. 处理支付

package main

import (
	"context"
	"log"
	
	"github.com/digota/digota/payment/paymentpb"
	"google.golang.org/grpc"
)

func main() {
	// 连接gRPC服务器
	conn, err := grpc.Dial("localhost:8080", grpc.WithInsecure())
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()
	
	// 创建支付客户端
	client := paymentpb.NewPaymentServiceClient(conn)
	
	// 创建支付请求
	req := &paymentpb.NewRequest{
		OrderId:         "order_123",
		PaymentProvider: paymentpb.PaymentProvider_Stripe,
		Currency:        paymentpb.Currency_USD,
		Total:           2000, // 20.00美元
		Email:           "customer@example.com",
		ReturnUrl:       "https://yourstore.com/thank-you",
	}
	
	// 调用创建支付方法
	payment, err := client.New(context.Background(), req)
	if err != nil {
		log.Fatal(err)
	}
	
	log.Printf("Payment created: %v", payment)
}

自定义扩展

Digota允许你通过实现特定接口来扩展功能:

package custom

import (
	"github.com/digota/digota/order/orderpb"
	"github.com/digota/digota/payment/paymentpb"
)

type CustomHandler struct{}

func (h *CustomHandler) BeforeOrderPaid(o *orderpb.Order, p *paymentpb.Payment) error {
	// 在订单支付前执行自定义逻辑
	return nil
}

func (h *CustomHandler) AfterOrderPaid(o *orderpb.Order, p *paymentpb.Payment) error {
	// 在订单支付后执行自定义逻辑
	return nil
}

然后在主程序中注册:

server.RegisterOrderHandler(&custom.CustomHandler{})

配置选项

Digota支持多种配置选项:

conf := &config.Config{
    PaymentProviders: []config.PaymentProvider{
        {
            Provider: "stripe",
            Secret:  "sk_test_...",
        },
    },
    Database: config.Database{
        Address:  []string{"localhost:27017"},
        Database: "digota",
    },
    Storage: config.Storage{
        Provider: "filesystem",
        Address:  "/path/to/storage",
    },
    Locker: config.Locker{
        Provider: "redis",
        Address:  "localhost:6379",
    },
}

总结

Digota为电商微服务开发提供了强大的基础功能,包括:

  1. 订单管理
  2. 支付处理
  3. 库存控制
  4. 用户认证
  5. 可扩展的插件系统

通过gRPC接口,你可以轻松地将Digota集成到现有的微服务架构中,或者基于它快速构建新的电商系统。Digota的模块化设计使得你可以根据需要选择使用全部或部分功能,也可以轻松扩展以满足特定业务需求。

对于生产环境使用,建议:

  • 实现适当的错误处理和日志记录
  • 添加监控和健康检查
  • 考虑安全最佳实践,如TLS加密通信
  • 根据业务需求扩展或自定义功能

Digota的文档和社区资源可以帮助你更深入地了解和使用这个框架。

回到顶部