您的位置: 首页 - 站长

idc销售网站php源代码宁波互联网

当前位置: 首页 > news >正文

idc销售网站php源代码,宁波互联网,做企业网站还有市场吗,哪家网站建设服务好什么是微服务?rpc架构的主要区别rpcx与grpc的区别rpcx:grpc:为什么grpc要使用http2,为什么不适应http1或者http3?为什么grpc要使用proto而不是json或者其他数据格式? 为什么rpcx快,快多少?rpcx的具体性能指标与grpc比较: 什么是微服务? 整体功能通过多个程序实现,每个程序… 什么是微服务?rpc架构的主要区别rpcx与grpc的区别rpcx:grpc:为什么grpc要使用http2,为什么不适应http1或者http3?为什么grpc要使用proto而不是json或者其他数据格式? 为什么rpcx快,快多少?rpcx的具体性能指标与grpc比较: 什么是微服务? 整体功能通过多个程序实现,每个程序只关心特定的业务. 优点: 简化功能: 单个服务之需要关心部分业务,实现起来更容易 更灵活: 不同服务间互不影响,可以使用不同的语言与技术栈,以及交给不同的成员/团队实现,便于团队合作/外包 隔离: 部分服务出问题不影响其他服务的功能 拓展: 更容易针对借口的实际压力情况进行横向拓展. rpc架构的主要区别 rpc架构的核心功能实际上是实现远程调用服务方法调用,客户端能像调用本地方法一样调用服务端和方法 那么核心问题就是如何实现接口的远程调用,选择什么网络协议,数据格式,这些决定了rpc架构是否跨语言,以及性能如何 可以写一个简单的rpc服务的demo去了解rpc是如何工作的 下面是一个很粗糙的demo;使用tcp进行通信,json进行编码的demo public.go package public //公共的方法与类 import (bytesencoding/binary )func Encode(data []byte) []byte {l : len(data)lBytes : IntToBytes(l)return append(lBytes, data…) }func IntToBytes(n int) []byte {data : int64(n)bytebuf : bytes.NewBuffer([]byte{})binary.Write(bytebuf, binary.BigEndian, data)return bytebuf.Bytes() }func BytesToInt(bys []byte) int {bytebuff : bytes.NewBuffer(bys)var data int64binary.Read(bytebuff, binary.BigEndian, data)return int(data) }type ReqData struct {ServerName stringTag string //标记哪个线程调用的服务,返回的时候带上可以将数据传输到对应的县城Data []byte } type RspData struct {Tag string //标记哪个线程调用的服务,返回的时候带上可以将数据传输到对应的县城Data []byte }type AddReq struct {NumA intNumB int }type AddRsp struct {Sum int } server.go package mainimport (bufioencoding/jsonfmtnetrpcdemo/public )type Server struct{}func (s *Server) Add(a *public.AddReq) *public.AddRsp {return public.AddRsp{Sum: a.NumA a.NumB} }// 服务调用 // 服务名方法名 // 封装对应的服务调用过程:根据方法名解析数据,并调用对应的方法 // 数据打包返回 // 这里做简化板手写处理:1. 没有实现自动化的服务方法注册;2. 我暂定使用uuid进行标识请求,以便于客户端可以将数据读取到对应的请求线程上,但事实上uuid过长,应该使用更为简单的标识方式 func serve(conn net.Conn) {defer conn.Close()reader : bufio.NewReader(conn)for {//解析长度lBytes : make([]byte, 8), err : reader.Read(lBytes[:])if err ! nil {fmt.Printf(数据读取失败%v\n, err)return}l : public.BytesToInt(lBytes)reqBytes : make([]byte, l)_, err reader.Read(reqBytes)if err ! nil {fmt.Printf(数据读取失败%v\n, err)return}go func(reqData []byte) {req : new(public.ReqData)err json.Unmarshal(reqData, req)if err ! nil {fmt.Printf(json 解析失败%v\n, err)return}//解析处理(这里只注册了一个服务接口)switch req.ServerName {case Server.Add:s : Server{}data : new(public.AddReq)err : json.Unmarshal(req.Data, data)if err ! nil {fmt.Printf(json 解析失败%v\n, err)return}rsp : s.Add(data)result, err : json.Marshal(rsp)if err ! nil {fmt.Printf(数据编码失败%v\n, err)return}rspBytes, err : json.Marshal(public.RspData{Tag: req.Tag, Data: result})if err ! nil {fmt.Printf(数据编码失败%v\n, err)return}rspData : append(public.IntToBytes(len(rspBytes)), rspBytes…)conn.Write(rspData)default:conn.Write([]byte(该方法没有注册))}}(reqBytes)}}func main() {listen, err : net.Listen(tcp, 127.0.0.1:9999)if err ! nil {fmt.Println(Listen() failed, err: , err)return}for {conn, err : listen.Accept() // 监听客户端的连接请求if err ! nil {fmt.Println(Accept() failed, err: , err)continue}go serve(conn) // 启动一个goroutine来处理客户端的连接请求} }client.go package mainimport (bufioencoding/jsonfmtnetrpcdemo/publictimegithub.com/google/uuid )type Client struct{ Conn net.Conn }func NewClient() *Client {conn, err : net.Dial(tcp, 127.0.0.1:9999)if err ! nil {fmt.Println(err : , err)return nil}return Client{Conn: conn} }// 每次调用都生成单独的uuid,并作为key,请求后select uuid对应的chan,直到有数据,读取数据,关闭通道,清除对应的map记录 var M map[string]chan ([]byte)// 启动客户端连接服务端并解析数据 func (c *Client) Run() {defer c.Conn.Close() // 关闭TCP连接reader : bufio.NewReader(c.Conn)for {lBytes : make([]byte, 8), err : reader.Read(lBytes[:])if err ! nil {fmt.Printf(数据读取失败)return}l : public.BytesToInt(lBytes)reqBytes : make([]byte, l)_, err reader.Read(reqBytes)if err ! nil {fmt.Printf(数据读取失败)return}//解析数据体并写入对应的chango func(data []byte) {rspData : new(public.RspData)err : json.Unmarshal(data, rspData)if err ! nil {fmt.Printf(数据解析失败)return}M[rspData.Tag] - rspData.Data}(reqBytes)} }// 我这边就不封装自动call了,直接手动call func (c *Client) Call(serverAndfunc string, data []byte) []byte {//生成uuidtag : uuid.New().String()reqData : public.ReqData{ServerName: serverAndfunc, Tag: tag, Data: data}r, err : json.Marshal(reqData)if err ! nil {fmt.Println(编码错误)return nil}Ch : make(chan []byte)defer close(Ch)defer delete(M, tag)M[tag] Chc.Conn.Write(append(public.IntToBytes(len®), r…))return -Ch }func main() {// 初始化mapM make(map[string]chan []byte)//建立tcp连接服务端client : NewClient()// 启动处理go client.Run()//模拟调用call方法req1 : public.AddReq{NumA: 1,NumB: 2,}reqdata1, err : json.Marshal(req1)if err ! nil {fmt.Println(编码错误)return}req2 : public.AddReq{NumA: 2,NumB: 2,}reqdata2, err : json.Marshal(req2)if err ! nil {fmt.Println(编码错误)return}//模拟多线程调用服务端go fmt.Printf(线程1调用结果:%s\n, string(client.Call(Server.Add, reqdata1)))go fmt.Printf(线程2调用结果:%s\n, string(client.Call(Server.Add, reqdata2)))time.Sleep(10 * time.Second) }client运行结果: 线程1调用结果:{Sum:3} 线程2调用结果:{Sum:4}当然这只是最简单的demo,模拟了使用tcp进行rpc远程调用,是否跨语言就在于双方时候都支持相同时协议与数据格式,比如使用了tcp的通信协议,那么只要支持tcp的的语言就可以使用打包成相同的数据结构就可以被服务端解析,而那些跨语言的rpc(比如grpc)在这方面做得更好,他们隐式的生成了接口代码,你不需要知道他是如何编码与解码的.可以直接使用,这对使用者是非常友好的. rpcx与grpc的区别 rpcx: 通信协议: 支持tcp,http,quic,kcp数据格式: 支持json,proto等多种解码器服务发现。支持 peer2peer、configured peers、zookeeper、etcd、consul 和 mDNS。其他: 多功能支持 https://github.com/smallnest/rpcx?tabreadme-ov-file性能优越 grpc: 通信协议:http2数据格式: proto服务发现: 支持etcd等多种组件.其他:https://www.cnblogs.com/leijiangtao/p/4453914.html自动生成photo文件规范,节省开发时间,方便快捷的部署微服务,跨语言开发等多种优势 为什么grpc要使用http2,为什么不适应http1或者http3? http1是一次请求一次响应的形式,要等上一次请求完成才能下一次请求,效率太低;而http2:每个请求都是一个双向流,一个连接可以包含多个流,等于是同时发起多个请求,效率更高当时,http3技术不成熟,并且http3相对来讲比较复杂.并且http2对于grpc来讲已经够用了. 为什么grpc要使用proto而不是json或者其他数据格式? proto格式只包含数据,即T-(L)-VTAG-LENGTH-VALUE方式编码,没有额外不用的:与{,不像json那样包含字段名数据的格式,数据结构更紧凑.数据体更小,传输的性能更好grpc作为一个跨语言的rpc架构,指定特定的数据类型可以更好的对接不同语言的接口 参考: https://segmentfault.com/a/1190000039158535 为什么rpcx快,快多少? 我翻阅了许多博客,他们都没有讲清楚为什么rpcx快.大多数都是在将rpcx与其他的比如grpc,阿里的Dubbo进行性能测试对比 rpcx的作者想做一个性能强大,服务治理的golang的rpc框架来补充golang rpc框架的空缺(虽然grpc与一些rpc架构开始支持go,但是他们都是走跨语言路线的.) rpcx作者的发展历程介绍到开始的rpcx就是对标准库的rpc进行的封装,rpc标准库就是一个性能非常优秀的库;客户度通过tcp连接和服务器通讯协议分为header和payload两部分header很简单包括服务名、方法和seqpayload包括序列化的数据。简单的数据格式,高效的网络通信使得他的性能非常的优秀. rpcx开始的版本就是根据标准库进行封装的,封装了服务发现,各种fail处理以及丰富的路由支持.所以rpcx事实上继承了标准rpc库的性能优势,并且在后期重构了代码并且提供了更加丰富的功能. 参考: rpcx简史 rpcx的具体性能指标与grpc比较: 模拟0ms处理时间 客户端并发数50020005000测试指标吞吐量(call/s)平均延迟(ms)p99延迟(ms)吞吐量(call/s)平均延迟(ms)rpcx20万2520万grpc14万2514万 模拟10ms处理时间 客户端并发数50020005000测试指标吞吐量(call/s)平均延迟(ms)p99延迟(ms)吞吐量(call/s)平均延迟(ms)rpcx5万102515万20grpc5万10259万30 模拟30ms处理时间 客户端并发数50020005000测试指标吞吐量(call/s)平均延迟(ms)p99延迟(ms)吞吐量(call/s)平均延迟(ms)rpcx1.8万10257万30grpc1.8万10256万20 参考:rpcx- GitHub 总结: 在并发数量增加的情况下,rpcx相比grpc的吞吐量与与p99延迟(处理99%请求的平均延迟)要更加优秀.