在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反射技术实现一套有默认值的配置解析库
在实际开发中,我们往往会给一个逻辑设计一套配置文件,用于根据不同环境加载不同配置。 比如生产环境和测试环境数据库的地址不一样,我们就需要在配置文件中设置不同的值。但是配置文件中又有一些相同值的配置项,比如数据库的名称等…...
【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...
《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...
Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)
引言:为什么 Eureka 依然是存量系统的核心? 尽管 Nacos 等新注册中心崛起,但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制,是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...
css的定位(position)详解:相对定位 绝对定位 固定定位
在 CSS 中,元素的定位通过 position 属性控制,共有 5 种定位模式:static(静态定位)、relative(相对定位)、absolute(绝对定位)、fixed(固定定位)和…...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...
微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...
