在CSDN学Golang场景化解决方案(微服务架构设计)
一,聚合器微服务设计模式
在Golang微服务架构设计中,聚合器(Aggregator)微服务设计模式是一种常见的应用程序体系结构模式。该模式旨在简化客户端与后端微服务之间的通信,并支持更高级别的操作,例如聚合多个后端服务的数据。以下是一个简单的示例:
- 首先定义一个聚合器微服务:
type AggregatorService struct {}func (s *AggregatorService) GetUserData(ctx context.Context, req *pb.UserRequest) (*pb.UserResponse, error) {// 获取用户信息。userClient := pb.NewUserServiceClient(userConn)userResp, err := userClient.GetUser(ctx, &pb.GetUserRequest{Id: req.Id})if err != nil {...}// 获取订单信息。orderClient := pb.NewOrderServiceClient(orderConn)orderResp, err := orderClient.GetOrders(ctx, &pb.GetOrdersRequest{UserId: req.Id})if err != nil {...}// 组装响应。resp := &pb.UserResponse{User: userResp.User,Orders: orderResp.Orders,}return resp, nil
}
- 在main函数中初始化gRPC服务器和相关连接:
func main() {// 初始化gRPC服务器。server := grpc.NewServer()// 连接用户服务和订单服务。userConn, err = grpc.Dial(userAddr, grpc.WithInsecure())if err != nil {...}orderConn, err = grpc.Dial(orderAddr, grpc.WithInsecure())if err != nil {...}// 注册聚合器微服务。pb.RegisterAggregatorServiceServer(server, &AggregatorService{})// 启动gRPC服务器。listen, err := net.Listen("tcp", addr)if err != nil {...}server.Serve(listen)
}
在这个设计中,我们定义了一个聚合器微服务,并使用两个后端微服务获取用户信息和订单信息。通过组装数据并返回响应,实现了一个简单的聚合器微服务。注意,在实际开发中需要进行错误处理、日志记录和安全措施等。
二,代理微服务设计模式
在Golang微服务架构设计中,代理(Proxy)微服务设计模式是一种常见的应用程序体系结构模式。该模式旨在为客户端提供透明的访问后端微服务的能力,同时还可以实现负载均衡和故障转移等功能。以下是一个简单的示例:
- 首先定义一个代理微服务:
type ProxyService struct {}func (s *ProxyService) GetUserData(ctx context.Context, req *pb.UserRequest) (*pb.UserResponse, error) {// 创建负载均衡器。lb := grpc.RoundRobin(lb.NewBalancerBuilder(userAddrs))// 创建用户服务客户端。userConn, err := grpc.DialContext(ctx, "", grpc.WithInsecure(), grpc.WithBalancer(lb))if err != nil {...}userClient := pb.NewUserServiceClient(userConn)// 调用用户服务获取用户信息。userResp, err := userClient.GetUser(ctx, &pb.GetUserRequest{Id: req.Id})if err != nil {...}// 组装响应。resp := &pb.UserResponse{User: userResp.User,Orders: []*pb.Order{},}return resp, nil
}
- 在main函数中初始化gRPC服务器和相关连接:
func main() {// 初始化gRPC服务器。server := grpc.NewServer()// 注册代理微服务。pb.RegisterProxyServiceServer(server, &ProxyService{})// 启动gRPC服务器。listen, err := net.Listen("tcp", addr)if err != nil {...}server.Serve(listen)
}
在这个设计中,我们定义了一个代理微服务,并使用负载均衡器和用户服务客户端获取用户信息。通过将代理微服务注册到gRPC服务器上,客户端可以透明地访问后端微服务。注意,在实际开发中需要进行错误处理、日志记录和安全措施等。
三,链式微服务设计模式
链式(Chain of Responsibility)微服务设计模式是一种常见的应用程序体系结构模式。该模式旨在通过将请求传递给多个处理程序来实现动态地将请求与其处理程序解耦。以下是一个简单的示例:
- 首先定义一个链式微服务:
type UserService struct {next Service
}func (s *UserService) SetNext(next Service) {s.next = next
}func (s *UserService) Handle(ctx context.Context, req *pb.Request) (*pb.Response, error) {// 如果可以处理,则直接处理并返回响应。if canHandle(req) {resp := handleRequest(req)return resp, nil}// 否则,将请求传递给下一个微服务进行处理。if s.next != nil {return s.next.Handle(ctx, req)}// 没有找到能够处理该请求的微服务,返回错误响应。return &pb.Response{Code: http.StatusNotFound,Error: "no service found to handle the request",}, nil
}
- 定义另一个微服务并设置为链式微服务的下一个节点:
type OrderService struct {next Service
}func (s *OrderService) SetNext(next Service) {s.next = next
}func (s *OrderService) Handle(ctx context.Context, req *pb.Request) (*pb.Response, error) {// 如果可以处理,则直接处理并返回响应。if canHandle(req) {resp := handleRequest(req)return resp, nil}// 否则,将请求传递给下一个微服务进行处理。if s.next != nil {return s.next.Handle(ctx, req)}// 没有找到能够处理该请求的微服务,返回错误响应。return &pb.Response{Code: http.StatusNotFound,Error: "no service found to handle the request",}, nil
}
- 在main函数中初始化链式微服务:
func main() {// 初始化微服务。userService := &UserService{}orderService := &OrderService{}// 设置链式关系。userService.SetNext(orderService)// 启动gRPC服务器。listen, err := net.Listen("tcp", addr)if err != nil {...}server.Serve(listen)
}
在这个设计中,我们定义了两个微服务,并通过设置它们之间的链式关系来实现请求的动态路由。如果第一个微服务无法处理请求,则将其转发给下
四,分支微服务设计模式
分支(Branch)微服务设计模式是一种常见的应用程序体系结构模式。该模式旨在通过将请求路由到多个处理程序来实现对请求和其处理程序之间的静态绑定。以下是一个简单的示例:
- 首先定义一个分支微服务:
type UserService struct {// ...
}func (s *UserService) Handle(ctx context.Context, req *pb.Request) (*pb.Response, error) {// 根据请求参数判断需要调用哪个方法。switch req.MethodName {case "createUser":resp := s.createUser(req)return resp, nilcase "getUser":resp := s.getUser(req)return resp, nildefault:return &pb.Response{Code: http.StatusNotFound,Error: "method not found",}, nil}
}func (s *UserService) createUser(req *pb.Request) *pb.Response {// 处理创建用户的逻辑。return &pb.Response{...}
}func (s *UserService) getUser(req *pb.Request) *pb.Response {// 处理获取用户的逻辑。return &pb.Response{...}
}
- 定义另一个微服务并设置为分支微服务下面的子节点:
type OrderService struct {// ...
}func (s *OrderService) Handle(ctx context.Context, req *pb.Request) (*pb.Response, error) {// 根据请求参数判断需要调用哪个方法。switch req.MethodName {case "createOrder":resp := s.createOrder(req)return resp, nilcase "getOrder":resp := s.getOrder(req)return resp, nildefault:return &pb.Response{Code: http.StatusNotFound,Error: "method not found",}, nil}
}func (s *OrderService) createOrder(req *pb.Request) *pb.Response {// 处理创建订单的逻辑。return &pb.Response{...}
}func (s *OrderService) getOrder(req *pb.Request) *pb.Response {// 处理获取订单的逻辑。return &pb.Response{...}
}
- 在main函数中初始化分支微服务:
func main() {// 初始化微服务。userService := &UserService{}orderService := &OrderService{}// 启动gRPC服务器并注册微服务。server := grpc.NewServer()pb.RegisterUserServiceServer(server, userService)pb.RegisterOrderServiceServer(server, orderService)// 监听端口并启动服务器。listen, err := net.Listen("tcp", addr)if err != nil {...}server.Serve(listen)
}
在这个设计中,我们定义了两个微服务,并通过在main函数中将它们注册到同一个gRPC服务器上来实现对请求和其处理程序之间的静态绑定。如果需要新增、删除或修改某个方法,则需要修改代码并重新部署整个应用程序。注意,在实际开发中需要进行错误处理、日志记录和安全措施等。
五,异步消息传递微服务设计模式
异步消息传递(Asynchronous Messaging)微服务设计模式是一种常见的应用程序体系结构模式。该模式旨在通过使用队列等方式实现应用程序内部不同微服务之间的通信。
以下是一个简单的示例:
- 定义一个事件结构体:
type Event struct {Type string // 事件类型Data interface{} // 事件数据
}
- 定义一个事件发布者:
type Publisher struct {queue chan<- *Event // 事件队列
}func NewPublisher(queue chan<- *Event) *Publisher {return &Publisher{queue: queue}
}func (p *Publisher) Publish(eventType string, data interface{}) error {event := &Event{Type: eventType,Data: data,}select {case p.queue <- event:return nildefault:return fmt.Errorf("failed to publish event %s", eventType)}
}
- 定义一个事件订阅者:
type Subscriber struct {queue <-chan *Event // 事件队列
}func NewSubscriber(queue <-chan *Event) *Subscriber {return &Subscriber{queue: queue}
}func (s *Subscriber) Consume() error {for event := range s.queue { // 遍历所有事件。switch event.Type { // 根据事件类型调用相应方法。case "user.created":handleUserCreated(event.Data.(*User))case "order.created":handleOrderCreated(event.Data.(*Order))default:log.Printf("unknown event type %s", event.Type)}if err != nil {// 异常处理}}return nil
}
- 在main函数中初始化事件队列、发布者和订阅者:
func main() {// 初始化事件队列。queue := make(chan *Event, 1000)// 启动事件发布者并发送消息。publisher := NewPublisher(queue)user := &User{ID: 1, Name: "Alice"}err := publisher.Publish("user.created", user)if err != nil {...}order := &Order{ID: 1, Product: "iPhone"}err = publisher.Publish("order.created", order)if err != nil {...}// 启动事件订阅者并处理消息。subscriber := NewSubscriber(queue)err = subscriber.Consume()if err != nil {...}
}
在这个设计中,我们使用异步消息传递模式来实现应用程序内部不同微服务之间的通信。当某个微服务产生一个事件时,它会将该事件通过队列等方式发布出去;而其他微服务则可以订阅该事件并执行相应的操作。这种方式能够增加系统的可靠性和扩展性,并且使得不同微服务之间解耦,从而降低了系统的复杂度。注意,在实际开发中需要进行错误处理、日志记录和安全措施等。
相关文章:
在CSDN学Golang场景化解决方案(微服务架构设计)
一,聚合器微服务设计模式 在Golang微服务架构设计中,聚合器(Aggregator)微服务设计模式是一种常见的应用程序体系结构模式。该模式旨在简化客户端与后端微服务之间的通信,并支持更高级别的操作,例如聚合多…...

centos7 yum安装mysql5.7
卸载mysql 以下指令查看是否安装过 rpm -qa | grep -i mysql 如果发现已经安装,需要卸载了再安装(据说,这样的卸载是不彻底的。) rpm -e mysql 卸载 mariadb yum -y remove mariadb-libs-1:5.5.68-1.el7.x86_64 下载和安装mys…...

安防视频汇聚平台EasyCVR视频广场面包屑侧边栏支持拖拽操作
智能视频监控平台EasyCVR能在复杂的网络环境中,将海量设备实现集中统一接入与汇聚管理,实现视频的处理与分发、录像与存储、按需调阅、平台级联等。 TSINGSEE青犀视频汇聚平台EasyCVR可拓展性强、视频能力灵活、部署轻快,可支持的主流标准协…...

爬虫007_python中的输出以及格式化输出_以及输入---python工作笔记025
首先看输出 输出这里,注意不能直接上面这样,18需要转换成字符串 可以看到python中这个字符串和数字一起的时候,数字要转换一下成字符串. 然后这里要注意%s 和%d,这个s指的是字符串,d指的是数字 注意后面的内容前面要放个% ,然后多个参数的话,那么这里用(),里面用,号隔开 然…...

485modbus转profinet网关连三菱变频器modbus通讯触摸屏监控
本案例介绍了如何通过485modbus转profinet网关连接威纶通与三菱变频器进行modbus通讯。485modbus转profinet网关提供了可靠的连接方式,使用户能够轻松地将不同类型的设备连接到同一网络中。通过使用这种网关,用户可以有效地管理和监控设备,从…...
话费充值接口文档
话费充值接口文档 接口版本:1.0 ―、引言 文档概述 本文档提供话费充值接口规范说明,提供一整套的完整的接入示例(http 接口)供商户参 考,可以帮助商户开发人员快速完成接口开发与联调,实现与话费充值系统的交易互联。 公司官网…...

windows系统的IP、路由、网关、内外网同时访问路由以及修改系统文件hosts的配置
当我们刚刚入职一家公司的时候、一般公司会给我下发一个ip地址和mac地址、还有访问一些公司的平台需要修改hosts之后的路由配置、以及第一次配置内网、如何内外网同时上网。 目录 一、ip的配置 1.1、IP的配置 1.2、mac地址的配置 1.3、内外网路由的配置(w11系统需…...

Kubespray-offline v2.21.0-1 下载 Kubespray v2.22.1 离线部署 kubernetes v1.25.6
文章目录 1. 目标2. 预备条件3. vcenter 创建虚拟机4. 系统初始化4.1 配置网卡4.2 配置主机名4.3 内核参数 5. 打快照6. 安装 git7. 配置科学8. 安装 docker9. 下载介质9.1 下载安装 docker 介质9.2 下载 kubespray-offline-ansible 介质9.3 下载 kubernetes 介质 10. 搬运介质…...
代码随想录训练营Day59单调栈Part01|739. 每日温度|496.下一个更大元素①
单调栈 单调栈应用场景:找当前元素左边/右边比当前元素大/小的第一个元素什么是单调栈:保证栈里面的元素递增/递减(需要自己定义)栈内保存什么:存入下标如何比较大小:栈和数组做映射递增?递减&…...

RPMsg-Lite上手
文章目录 1、rpmsg-lite介绍2、rpmsg-lite 应用 现在的芯片非常复杂,很多都是包含多个核,特别是片上系统(SoC),一颗芯片上不仅包含了很多个核心,并且很多核心都是异构的。 为了最大限度的发挥他们的性能&am…...
基于YOLOv8 的 多边形区域内目标检测,跟踪,计数
文章大纲 使用OpenCV 进行多边形 角点获取yolov5 的样例实现基于 roboflow 开源库的实现roboflow 开源库 介绍基于YOLOv8 track 的 Polygon Zone 计数参考文献与学习路径自己实现使用 开源库使用OpenCV 进行多边形 角点获取 import cv2 def SetPoints(windowname, img):"…...

STSP中用于记录节点和旅行回路的四种数据结构
STSP中用于记录节点和旅行回路的四种数据结构 双链表结构2-level tree卫星结构k-level卫星结构树参考文献 对于TSP是是历史悠久的研究问题,直至现在已经有了很多成熟高效的算法来求解问题。在拥有好的求解算法的同时,优秀的数据结构可以同时大幅提升问题…...

【Spring】AOP切点表达式
文章目录 1、语法2、通配符3、execution4、within5、annotation6、args7、args8、bean9、this10、target11、target12、within13、表达式组合14、补充 1、语法 动作关键词(访问修饰符 返回值 包名.类/接口名 .方法名(参数)异常名) 举例: execution(public User c…...

设计模式再探——代理模式
目录 一、背景介绍二、思路&方案三、过程1.代理模式简介2.代理模式的类图3.代理模式代码4.代理模式还可以优化的地方5.代理模式的项目实战,优化后(只加了泛型方式,使用CGLIB的代理) 四、总结五、升华 一、背景介绍 最近在做产品过程中对于日志的统一…...

MySQL日志——查询日志
1.查询日志 show variables like %general%;修改mysql的配置文件 /etc/my.cnf文件,添加如下内容: #该选项用来开启查询日志,可选值:0或者1;0代表关闭,1代表开启 general_log1 #设置日志的文件名࿰…...

Java版本工程行业管理系统源码-专业的工程管理软件-提供一站式服务 em
工程项目管理软件(工程项目管理系统)对建设工程项目管理组织建设、项目策划决策、规划设计、施工建设到竣工交付、总结评估、运维运营,全过程、全方位的对项目进行综合管理 工程项目各模块及其功能点清单 一、系统管理 1、数据字典&#…...

pytorch的CrossEntropyLoss交叉熵损失函数默认是平均值
pytorch中使用nn.CrossEntropyLoss()创建出来的交叉熵损失函数计算损失默认是求平均值的,即多个样本输入后获取的是一个均值标量,而不是样本大小的向量。 net nn.Linear(4, 2) loss nn.CrossEntropyLoss() X torch.rand(10, 4) y torch.ones(10, dt…...

【力扣】206. 反转链表 <链表指针>
【力扣】206. 反转链表 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 示例 1 输入:head [1,2,3,4,5] 输出:[5,4,3,2,1] 示例 2 输入:head [1,2] 输出:[2,1] 示例 3 输入:…...

Java包装类(自动拆装箱)
包装类 为什么要有包装类? 在面向对象中,“一切皆为对象”,但是基本数据类型不符合这一理念,为了让基本类型也称为对象 便于类型之间的转化,数据类型之间的基本操作 转换方式: int ——> Integer ne…...
使用Golang反射技术实现一套有默认值的配置解析库
在实际开发中,我们往往会给一个逻辑设计一套配置文件,用于根据不同环境加载不同配置。 比如生产环境和测试环境数据库的地址不一样,我们就需要在配置文件中设置不同的值。但是配置文件中又有一些相同值的配置项,比如数据库的名称等…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...

DAY 47
三、通道注意力 3.1 通道注意力的定义 # 新增:通道注意力模块(SE模块) class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...

《基于Apache Flink的流处理》笔记
思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...