Golang微服务基础技术

简介: Golang微服务基础技术

单体式和微服务

单体式架构服务

------过往大家熟悉的服务器

特性:

1.复杂性随着开发越来越高,遇到问题解决困难。

2. 技术债务逐渐上升

3. 耦合度高,维护成本大

出现bug,不容易排查

解决旧bug,会出新bug

4. 持续交付时间较长

5. 技术选型成本高,风险大。

6. 扩展性较差

1.垂直扩展:通过增加单个系统程序的负荷来实现扩展。

2.水平扩展:通过增加更多的系统成员来实现扩展。

微服务

· 优点

1.职责单一

2.轻量级通信

3.独立性

4.迭代开发

· 缺点

  1. 运维成本高
  2. 分布式复杂度
  3. 接口成本高
  4. 重复性劳动
  5. 业务分离困难

单体式和微服务对比

RPC协议

什么是RPC

Remote Procedure Call Protocol – 远程过程调用协议!

IPC:进程间通信

RPC:远程进程通信 — 应用层协议(http协议同层),底层使用TCP实现。

回顾:

OSI7层模型架构:物理层,数据链路层,网络层,传输层,会话层,表示层,应用层

TCP/IP4层架构:链路层,网络层,传输层,应用层

理解RPC:

像调用本地函数一样,去调用远程函数。

通过rpc协议,传递:函数名,函数参数,达到在本地,调用远端函数,得返回值到本地的目标

为什么微服务使用RPC:

1.每个服务都被封装成进程,彼此“独立”。

2.进程和进程之间,可以使用不同的语言实现。

RPC入门使用

远程 — 网络!!

回顾:Go语言 一般性 网络socket通信

server端:

net.Listen() – listener 创建监听器

listener.Accpet() – conn 启动监听,建立连接

conn.read()

conn.write()

defer conn.Close() / listener.Close()

client端:

net.Dial() – conn

conn.Write()

conn.Read()

defer conn.Close()

RPC使用的步骤

-------服务端

1.注册RPC服务对象。给对象绑定方法(1.定义类,2.绑定类方法)

rpc.RegisterName("服务名",回调对象)
  1. 创建监听器
listener,err := net.Listen()
  1. 建立连接
conn,err := listener.Accept()
  1. 将连接 绑定rpc服务
rpc.ServeConn(conn)

------ 客户端:

1.用rpc连接服务器。

conn,err := rpc.Dial()

2.调用远程函数。

conn.Call("服务名.方法名",传入参数,传出参数)

RPC相关函数

1.注册rpc服务

func (server *Server) RegisterName(name string,rcvr interface{}) error
参1:服务名。字符串类型。
参2:对应rpc对象。该对象绑定方法要满足如下条件:
     1.方法必须是导出的----包外可见,首字母大写。
     2.方法必须有两个参数,都是导出类型,内建类型。
     3.方法的第二个参数必须是“指针” (传出参数)
     4.方法只有一个 error接口类型的返回值。
举例:
type World stuct{
}
func(this *World) HelloWorld(name string,resp *string) error{
}
rpc.RegisterName("服务名",new(World))

2.绑定rpc服务

func (server *Server) ServerConn(conn io.ReadWriteCloser)
  conn:成功建立好连接的 socket -- conn

3.调用远程函数:

func (client *Client) Call(serviceMethod string,args interface{},reply interface{}) error
  serviceMethod:“服务器.方法名”
  args:传入参数,方法需要的数据。
  reply:传出参数。定义var变量,&变量名  完成传参。

编码实现

server端

package main
 
import (
  "net/rpc"
  "fmt"
  "net"
)
// 定义类对象
type World struct {
  
}
// 绑定类方法
func (this *World) HelloWorld (name string,resp *string) error {
  *resp = name + "你好!"
  return nil
}
func main(){
  
  // 1.注册RPC服务,绑定对象方法
  err := rpc.RegisterName("hello",new(World))
  if err != nil{
    fmt.Println("注册 rpc 服务失败!",err)
    return
  }
  // 2.设置监听
  listener,err := net.Listen("tcp","127.0.0.1:8802")
  if err != nil{
    fmt.Println("net.Listen err:",err)
    return
  }
  defer listener.Close()
  
  fmt.Println("开始监听...")
  // 3.建立连接
  conn,err := listener.Accept()
  if err != nil{
    fmt.Println("Accpet() err:",err)
    return 
  }
  defer conn.Close()
  fmt.Println("连接成功....")
  // 4. 绑定服务
  rpc.ServeConn(conn)
}

client端

package main 
import (
  "net/rpc"
  "fmt"
)
func main(){
  // 1.用rpc连接服务器  --Dial()
  conn,err := rpc.Dial("tcp","127.0.0.1:8802")
  if err != nil {
    fmt.Println("Dial err:",err)
    return 
  }
  defer conn.Close()
  // 2.调用远程函数
  var reply string   // 接收返回值   --- 传出参数
  err = conn.Call("hello.HelloWorld","李白",&reply)
  if err != nil {
    fmt.Println("Call err:",err)
    return 
  }
  fmt.Println(reply)
}

json版rpc

使用 nc -l 127.0.0.1 8800 充当服务器

2_client.go充当客户端,发起通信。 --乱码

因为,rpc使用了go语言特有的序列化gob,其他编程语言不能解析

使用通用的序列化反序列化。 --json,protobuf

修改客户端

修改客户端,使用jsonrpc:
conn,err := jsonrpc.Dial("tcp","127.0.0.1:8800")

修改服务器端

修改服务器端,使用jsonrpc:

jsonrpc.ServerConn(conn)

如果,绑定方法返回值的error不为空?无论传出参数是否有值,服务端都不会返回数据。

rpc封装

3_design.go

package main 
import (
   "net/rpc/jsonrpc"
   "net/rpc"
)
// 要求,服务端在注册rpc对象时,能让编译期检查出  注册对象是否合法
// 创建接口,在接口中定义方法原型
type MyInterface interface{
  HelloWorld(string,*string) error
}
// 调用该方法,需要给 i 传参,参数应该是实现了  HelloWorld 方法的类对象
func RegisterService(i MyInterface) {
  rpc.RegisterName("hello",i)
}
//-------------------客户端调用
// 定义类
type Myclient struct {
  c *rpc.Client
}
// 由于使用了c调用Call,因此需要初始化c
func InitClient(addr string) Myclient {
  conn,_ := jsonrpc.Dial("tcp",addr)
  
  return Myclient{c:conn}
}
// 实现函数,原型参照上面的Interface来实现
func (this *Myclient) HelloWorld (a string,b *string) error {
  // 参数1,参照上面的 Interface,RegisterName  而来,a:传入参数  b:传出参数
  return this.c.Call("hello.HelloWorld",a,b)
}

1_server.go

package main
 
import (
  // "net/rpc"
  "net/rpc/jsonrpc"
  "fmt"
  "net"
)
// 定义类对象
type World struct {
  
}
// 绑定类方法
func (this *World) HelloWorld (name string,resp *string) error {
  *resp = name + "你好!"
  return nil
}
func main(){
  // 1.注册RPC服务,绑定对象方法
  RegisterService(new(World))
  // err := rpc.RegisterName("hello",new(World))
  // if err != nil{
  //  fmt.Println("注册 rpc 服务失败!",err)
  //  return
  // }
  // 2.设置监听
  listener,err := net.Listen("tcp","127.0.0.1:8803")
  // listener,err := InitClient("127.0.0.1:8803")
  if err != nil{
    fmt.Println("net.Listen err:",err)
    return
  }
  defer listener.Close()
  
  fmt.Println("开始监听...")
  // 3.建立连接
  conn,err := listener.Accept()
  if err != nil{
    fmt.Println("Accpet() err:",err)
    return 
  }
  defer conn.Close()
  fmt.Println("连接成功....")
  // 4. 绑定服务
  // rpc.ServeConn(conn)
  jsonrpc.ServeConn(conn)
}

2_client.go

package main 
import (
  "net/rpc"
  "fmt"
)
func main01(){
  // 1.用rpc连接服务器  --Dial()
  conn,err := rpc.Dial("tcp","127.0.0.1:8802")
  if err != nil {
    fmt.Println("Dial err:",err)
    return 
  }
  defer conn.Close()
  // 2.调用远程函数
  var reply string   // 接收返回值   --- 传出参数
  err = conn.Call("hello.HelloWorld","李白",&reply)
  if err != nil {
    fmt.Println("Call err:",err)
    return 
  }
  fmt.Println(reply)
}
// 结合 3_design.go 测试
func main(){
  myClient := InitClient("127.0.0.1:8803")
  var resp string 
  err := myClient.HelloWorld("杜甫",&resp)
  if err != nil{
    fmt.Println("HelloWorld err:",err)
    return
  }
  fmt.Println(resp,err)
}

ProtoBuf认识与使用

protobuf简介

Protobuf是Protocol Buffers的简称,它是Google公司开发的一种描述语言,是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化。他很适合做数据存储或者RPC数据交换格式

可以用于通信协议,数据存储等领域的语言无关,平台无关,可扩展的序列化结构数据格式。目前提供了C++,Java,Python三种语言的API。

Protobuf刚开源是的定位类似于xml,json等数据描述语言,通过附带工具生成代码并实现将结构化数据序列化的功能,这里我们更关注的是Protobuf作为接口规范的描述语言,可以作为设计安全的跨语言RPC接口的基础工具。

需要了解两点

  1. protobuf是类似于json一样的数据描述语言(数据格式)
  2. protobuf非常适合于RPC数据交换格式

接着我们来看一下protobuf的优势和劣势:

优势

1.序列化后面积比Json和Xml很小,适合网络传输

2.支持跨平台多语言

3.消息格式升级和兼容性还不错

4.序列化反序列化速度很快,快于json的处理速度

劣势

  1. 应用不够广(相比xml和json)
  2. 二进制格式导致可读性差
  3. 缺乏自描述

protobuf的安装

1.下载protobuf

方法一:===》git clone https://github.com/protocolbuffers/protobuf.git
方法二:===》 或者将准备好的压缩包进行拖入
      解压到 $GOPATH/src/github.com/protocolbuffers/下面
      Unizip protobuf.zip
  1. 安装(Ubuntu)

3.测试protobuf编译工具

protoc -h

如果正常输出 相关指令 没有报任何error,为安装成功

4.安装protobuf的go语言插件

感谢大家观看,我们下次见

目录
相关文章
|
21天前
|
Kubernetes Cloud Native Docker
探索云原生技术之旅:从容器到微服务
【8月更文挑战第42天】本文将带你踏上一场云原生技术的奇妙之旅,我们将从容器技术的基础出发,逐步深入到微服务架构的世界。你将了解到如何利用Docker和Kubernetes简化应用部署与管理,以及如何通过微服务设计原则构建可扩展、灵活的系统。准备好一起探索这些令人兴奋的技术了吗?让我们开始吧!
56 14
|
13天前
|
运维 Kubernetes Cloud Native
探索云原生技术:容器化与微服务架构的融合之道
【9月更文挑战第18天】在数字化转型的浪潮中,云原生技术以其灵活性、可扩展性成为企业创新的强大引擎。本文将深入探讨云原生技术的核心概念,特别是容器化和微服务架构如何相辅相成,共同推动现代应用的开发与部署。通过实际代码示例,我们将揭示这些技术如何简化运维,加速产品上市时间,并提高系统的可靠性和弹性。无论你是开发人员、架构师还是IT决策者,这篇文章都将为你提供宝贵的洞见和实践指导。
18 2
|
13天前
|
Kubernetes Cloud Native Java
云原生技术之旅:从容器化到微服务架构
【9月更文挑战第18天】云原生技术正改变着我们构建、部署和管理应用的方式。本文将通过一次虚拟的旅行,带领读者探索云原生的核心概念,如容器化、微服务、持续集成与交付等。我们将以一个实际案例为线索,逐步展开对Kubernetes集群管理、Docker容器创建和Spring Boot微服务开发的讨论。就像在旅途中不断发现新风景一样,您将了解到这些技术如何协同工作,提升开发效率和应用性能。准备好了吗?让我们启航!
|
17天前
|
Kubernetes Cloud Native Docker
云原生技术之旅:从容器到微服务
【9月更文挑战第14天】随着云计算的蓬勃发展,云原生技术已成为现代软件开发的重要组成部分。本文将深入探讨云原生的核心概念,包括容器化、微服务架构以及它们如何共同推动企业快速创新。通过实际案例,我们将展示如何利用Kubernetes和Docker等工具构建和管理高效的云原生应用。无论你是初学者还是经验丰富的开发者,这篇文章都将为你提供宝贵的知识和技能,帮助你在云原生时代乘风破浪。
40 5
|
19天前
|
运维 Cloud Native Devops
云原生架构的崛起与实践云原生架构是一种通过容器化、微服务和DevOps等技术手段,帮助应用系统实现敏捷部署、弹性扩展和高效运维的技术理念。本文将探讨云原生的概念、核心技术以及其在企业中的应用实践,揭示云原生如何成为现代软件开发和运营的主流方式。##
云原生架构是现代IT领域的一场革命,它依托于容器化、微服务和DevOps等核心技术,旨在解决传统架构在应对复杂业务需求时的不足。通过采用云原生方法,企业可以实现敏捷部署、弹性扩展和高效运维,从而大幅提升开发效率和系统可靠性。本文详细阐述了云原生的核心概念、主要技术和实际应用案例,并探讨了企业在实施云原生过程中的挑战与解决方案。无论是正在转型的传统企业,还是寻求创新的互联网企业,云原生都提供了一条实现高效能、高灵活性和高可靠性的技术路径。 ##
27 3
|
27天前
|
Kubernetes Cloud Native Docker
云原生技术:容器化与微服务架构的融合之道
【9月更文挑战第4天】在数字化时代的浪潮下,企业追求敏捷、高效、可扩展的IT架构成为共识。云原生技术作为现代软件部署的黄金标准,其核心理念在于推动应用的快速迭代与无缝迁移。本文将深入探讨云原生技术的精髓——容器化与微服务架构如何相互促进,共同构建起适应云计算环境的应用生态系统。我们将通过实际案例,揭示如何在云平台上利用这些技术实现服务的解耦、弹性伸缩及自动化管理,进而提升企业的竞争力。
|
29天前
|
存储 监控 Go
面向OpenTelemetry的Golang应用无侵入插桩技术
文章主要讲述了阿里云 ARMS 团队与程序语言与编译器团队合作研发的面向OpenTelemetry的Golang应用无侵入插桩技术解决方案,旨在解决Golang应用监控的挑战。
|
2月前
|
存储 设计模式 前端开发
|
2月前
|
安全 网络安全 数据安全/隐私保护
云原生技术探索:容器化与微服务架构的实践之路网络安全与信息安全:保护数据的关键策略
【8月更文挑战第28天】本文将深入探讨云原生技术的核心概念,包括容器化和微服务架构。我们将通过实际案例和代码示例,展示如何在云平台上实现高效的应用部署和管理。文章不仅提供理论知识,还包含实操指南,帮助开发者理解并应用这些前沿技术。 【8月更文挑战第28天】在数字化时代,网络安全和信息安全是保护个人和企业数据的前线防御。本文将探讨网络安全漏洞的成因、加密技术的应用以及提升安全意识的重要性。文章旨在通过分析网络安全的薄弱环节,介绍如何利用加密技术和提高用户警觉性来构建更为坚固的数据保护屏障。
|
2月前
|
运维 Cloud Native 开发者
云原生技术演进:从微服务到无服务器的旅程
【8月更文挑战第20天】在数字化时代的浪潮中,云原生技术如同一艘航船,承载着企业转型的梦想与挑战。本文将深入探讨云原生技术的发展路径,从微服务的兴起到无服务器架构的革新,揭示这一技术演进背后的逻辑与动力。通过分析云原生技术的优势、面临的挑战以及未来的发展趋势,我们将描绘出一幅云原生技术演进的宏伟蓝图。

热门文章

最新文章