GO语言
文章平均质量分 72
GO语言编程技术知识分享!
千锋教育官方
千锋立足于职业教育培训领域多年,现有教研讲师团队300余人。与国内20000余家IT相关企业建立人才输送合作关系,十年间累计培养超20余万泛IT人才,累计向互联网输出学科视频880余套,累积播放量超上亿次。
展开
-
手把手带你进行Golang环境配置
刚开始写Go时,其实我是用的也是VSCode,但是我在使用时发现,VSCode总是不自动提示,并且设置了自动保存也常常自动失效,经历了几次折腾之后,还是拥抱了专为Go开发的IDE,Goland!Goland的安装,破解,在此不做叙述。整体来说,Go配置环境还是挺轻松的,和Python差不多,并且会自动添加环境变量。上述安装过程没问题后,打开CMD窗口,输入go version命令,如图所示。由于已经是1.11+版本,我们以后使用go mod进行管理依赖,不需要配置。6、安装进行中,等到安装完成。原创 2020-10-16 15:40:26 · 408 阅读 · 0 评论 -
RPC编程定义与原理
在编程实现过程中,服务器端需要注册结构体对象,然后通过对象所属的方法暴露给调用者,从而提供服务,该方法称之为输出方法,此输出方法可以被远程调用。当然,在定义输出方法时,能够被远程调用的方法需要遵循一定的规则。上述代码是go语言官方给出的对外暴露的服务方法的定义标准,其中包含了主要的几条规则,分别是:1、对外暴露的方法有且只能有两个参数,这个两个参数只能是输出类型或内建类型,两种类型中的一种。2、方法的第二个参数必须是指针类型。3、方法的返回类型为error。4、方法的类型是可输出的。原创 2020-10-20 15:05:27 · 233 阅读 · 0 评论 -
RPC简介及原理介绍
这种调用的过程跨越了物理服务器的限制,是在网络中完成的,在调用远端服务器上程序的过程中,本地程序等待返回调用结果,直到远端程序执行完毕,将结果进行返回到本地,最终完成一次完整的调用。特别是目前随着互联网技术的快速迭代和发展,用户和需求几乎都是以指数式的方式在高速增长,这个时候绝大多数情况下程序都是部署在多台机器上,就需要在调用其他物理机器上的程序的情况。同时,在之前的《Go语言微服务理论与实践》课程中,我们已经学习过Protobuf协议,这也是一种数据编解码的协议,在RPC框架中使用的更广泛。原创 2020-10-20 15:11:14 · 259 阅读 · 0 评论 -
gRPC介绍和安装
刚刚搭建完grpc-go库环境后,还暂时不会写grpc的程序。在下载的grpc-go库的根目录中,存在有examples目录,存放了官方提供的演示案例。gRPC开源库支持诸如:C++,C#,Dart,Go,Java,Node,Objective-C,PHP,Python,Ruby,WebJS等多种语言,开发者可以自行在gRPC的github主页库选择查看对应语言的实现。如果采用2.2.2中的clone方式下载安装,因为grpc-go库中调用了其他外部库内容,因此,需要额外准备相关的代码库环境。原创 2020-10-21 10:49:28 · 754 阅读 · 1 评论 -
RPC与Protobuf结合使用
在服务的方法定义中,使用orderMap模拟初始订单数据库,方便案例查询展示。GetOrderInfo方法有两个参数,第一个是message.OrderRequest,作为调用者传递的参数,第二个是message.OrderInfo,作为调用返回的参数,通过此处的两个参数,将上文通过.proto定义并自动生成的Go语言结构体数据结合起来。需求:假设在一个系统中,有订单模块(Order),其他模块想要实现RPC的远程工程调用,根据订单ID和时间戳可以获取订单信息。现在,我们来进行需求的编程实现。原创 2020-10-21 10:55:11 · 287 阅读 · 1 评论 -
Go语言:gRPC调用
..//订单服务service定义//服务端流模式我们可以看到与之前简单模式下的数据作为服务接口的参数和返回值不同的是,此处服务接口的返回值使用了stream进行修饰。通过stream修饰的方式表示该接口调用时,服务端会以数据流的形式将数据返回给客户端。...//订单服务service定义//客户端流模式//订单服务service定义//双向流模式。原创 2020-10-22 10:45:40 · 621 阅读 · 0 评论 -
gRPC框架使用
如果定义的.proto文件,如本案例中所示,定义中包含了服务接口的定义,而我们想要使用gRPC框架实现RPC调用。利用之前所掌握的内容,gRPC框架支持对服务的定义和生成。在.proto定义好服务接口并生成对应的go语言文件后,需要对服务接口做具体的实现。我们通过proto文件定义了数据结构的同时,还定义了要实现的服务接口,GetOrderInfo即是具体服务接口的定义,在GetOrderInfo接口定义中,OrderRequest表示是请求传递的参数,OrderInfo表示处理结果返回数据参数。原创 2020-10-22 10:50:36 · 228 阅读 · 0 评论 -
拦截器的使用方法场景
接下来就自定义实现func,符合UnaryServerInterceptor的标准,在该func的定义中实现对token的验证逻辑。//通过metadataif!exist {return nil, status.Errorf(codes.Unauthenticated, "无Token认证信息")ok {ok {if appKey!return nil, status.Errorf(codes.Unauthenticated, "Token 不合法")//通过token验证,继续处理请求。原创 2020-10-23 14:45:47 · 218 阅读 · 0 评论 -
TLS验证和Token认证
在web应用的开发过程中,我们往往还会使用另外一种认证方式进行身份验证,那就是:Token认证。基于Token的身份验证是无状态,不需要将用户信息服务存在服务器或者session中。在gRPC中,允许开发者自定义自己的认证规则,通过设置自定义的认证规则。因此,开发者可以实现以上接口,来定义自己的token信息。//token认证//组织token信息}, nil//是否基于TLS认证进行安全传输。原创 2020-10-23 14:52:24 · 279 阅读 · 0 评论 -
Consul服务发现原理
服务注册到Consul可以通过 HTTP API(8500 端口)的方式,也可以通过 Consul 配置文件的方式。6、Consul Server查询到Service B当前的信息返回,最终Program D拿到了Service B的所有部署的IP和端口,然后就可以选择Service B的其中一个部署并向其发起请求了。Consul Client 可以认为是无状态的,它将注册信息通过RPC转发到Consul Server,服务信息保存在Server的各个节点中,并且通过Raft实现了强一致性。原创 2020-10-28 16:07:17 · 293 阅读 · 0 评论 -
启动consul服务命令
终端命令行下启动consul的dev模式后,通过members命令查看节点信息,除此以外,还可以使用Http的浏览器访问的模式,查看节点信息。consul启动,正常运行后,打开浏览器,在地址栏中键入:http://localhost:8500。集群中只包含一个节点,唯一的节点被选举成为Leader节点。在consul启动后,可以通过命令查看节点的信息。Type:节点的类型,有两种:server、client。在节点运行终端中执行:ctrl + c,表示退出节点运行。在新终端中,执行如上操作。原创 2020-10-28 16:10:40 · 3549 阅读 · 0 评论 -
GO语言:微服务管理--服务发现
third-party registration模式也有一些优势和劣势:主要优势是使得服务从服务注册表中被解耦,你不必为开发者使用的每种开发语言和框架实现服务注册的逻辑,相反,服务实例的注册被一个专有服务以集中式的方式处理。服务发现的关键是服务注册表,服务注册表是可用服务实例的数据库,它提供了管理和查询使用的API。在一个微服务应用中,一组运行的服务实例是动态变化的,实例有动态分配的网络地址,因此,为了使得客户端能够向服务发起请求,必须要要有服务发现机制。服务实例的注册一般是通过。原创 2020-11-03 09:57:42 · 230 阅读 · 0 评论 -
go语言:微服务管理--单点故障与分布式
Server节点有一个Leader和多个Follower,Leader节点会将数据同步到Follower,Server的数量推荐是3个或者 5个,在Leader挂掉的时候会启动选举机制产生一个新的 Leader。传统的解决方案是采用一个备用节点,这个备用节点定期给当前主节点发送ping包,主节点收到ping包以后向备用节点发送回复ACK,当备用节点收到回复时就会认为当前主节点还活着,让他继续提供服务。主节点负责分发任务,从节点负责处理任务,当我们的主节点发生故障时,整个系统就瘫痪了。原创 2020-11-03 10:09:34 · 211 阅读 · 0 评论 -
GO语言:Protobuf协议Go语言实践 Davie
protoc编译器正常运行需要进行环境变量配置,将protocke执行文件所在目录添加到当前系统的环境变量中。windows系统下可以直接在Path目录中进行添加;执行 protoc --go_out=. test.proto 生成对应的 person.pb.go 文件。并构建对应的example目录,存放生成的person.pb.go文件。具体的对应的系统的环境变量配置可以阅读解压后与bin目录同级的readme.txt的文件内容。的文件,并编写代码。2、编译.proto文件,生成Go语言文件。原创 2020-11-04 16:09:24 · 253 阅读 · 0 评论 -
GO语言:Protobuf协议语法及原理
Varint中的每个byte的最高位bit有特殊的含义,如果该位为1,表示后续的byte也是该数字的一部分,如果该位为0,则结束。Key用来标识具体的field,在解包的时候,Protocol Buffer根据Key就可以知道相应的Value应该对应于消息中的哪一个field。对于可选的Field,如果消息中不存在该field,那么在最终的Message Buffer中就没有该field,这些特性都有助于节约消息本身的大小。它用一个或多个字节来表示一个数字,值越小的数字使用越少的字节数。原创 2020-11-04 16:13:31 · 194 阅读 · 0 评论 -
GO语言:微服务--定义和标准
另外,一般微服务在系统内部,通常是无状态的,而我们的用户在进行业务操作时,往往是跨业务模块进行操作,且需要是有状态的,在此时的这个系统架构中,也无法解决这个问题。服务调用者通过服务管理框架进行寻址,根据特定的算法,找到对应的服务,或者将服务的注册信息缓存到本地,这样提高性能。异步消息的方式在分布式系统中有特别广泛的应用,他既能减低调用服务之间的耦合,又能成为调用之间的缓冲,确保消息积压不会冲垮被调用方,同时能保证调用方的服务体验,继续干自己该干的活,不至于被后台性能拖慢。这就是服务的发现、识别与管理问题。原创 2020-11-05 16:09:56 · 198 阅读 · 0 评论 -
GO语言:Protobuf简介
对于单独部署,独立运行的微服务实例而言,在业务需要时,需要与其他服务进行通信,这种通信方式是进程之间的通讯方式(inter-process communication,简称IPC)。支持前后兼容是非常重要的一个特点,在庞大的系统开发中,往往不可能统一完成所有模块的升级,为了保证系统功能正常不受影响,应最大限度保证通讯协议的向前兼容和向后兼容。在同步过程调用的具体实现中,有一种实现方式为RPC通信方式,远程过程调用(英语:Remote Procedure Call,缩写为 RPC)。原创 2020-11-05 16:14:38 · 228 阅读 · 0 评论 -
GO语言:微服务--构建单体应用
然而,无论是炒作还是怀疑,不可否认,微服务架构模式具有非常明显的优势 —- 特别是在实施敏捷开发和复杂的企业应用迭代开发方面。如上我们从传统的构建项目应用和项目架构拆解的角度来给大家解释了什么是单体应用,单体的特点以及传统的应用的架构设计。类似的单体应用在我们以往的互联网发展和企业应用中使用的非常普遍,现在也仍然很多企业都是类似的单体应用。但是,随着需求的增长,业务的变化,单体应用在慢慢发展和迭代后,也会遇到一些问题,单体应用的瓶颈会逐步显现。让我们从我们原本最熟悉的创建一个应用和一个普通的项目开始说起。原创 2020-11-06 10:38:45 · 330 阅读 · 1 评论 -
GO语言:微服务--走向单体地狱
最后,经过了上面几个方面的问题的罗列,我们总结一下:当我们开发个业务量小,功能适量的一个项目应用时,通过单体应用的开发,就可以满足我们的开发需求,实现业务功能。当业务量快速增长,系统持续开发迭代时,我们的应用体积和业务复杂程度会越来越高,以至于影响开发人员的开发效率,提高了项目的维护成本,我们的项目会遇到各种瓶颈问题,应用程序的持续扩展能力受到限制,性能也因此受到影响。但是,随着系统业务的不断增长,代码量不断增加,我们维护创建的单体应用系统的性能和维护成本都会受到限制,限制了我们继续新增新业务的能力。原创 2020-11-06 10:41:20 · 240 阅读 · 1 评论 -
GO语言:微服务架构模式解决复杂问题
为了提高系统性能,提高处理数据的能力,可以将原本是耦合,依赖在同一个系统中的业务模块拆分为小规模的多个业务模块,也就是我们说的微服务的实现架构,每个微服务都只实现核心功能,比如订单模块拆分为一个微服务,支付模块拆分为一个微服务。在拆分的过程中,因为每个微服务是独立部署的,所以订单模块对应的订单表存在于一个数据库db1中,支付模块所对应的支付表存在于另外一个数据库db2中。数据库中,同一张表格的数据量过大时,我们的查询等业务在操作数据库时会变得效率下降,我们需要通过其他的方式来提高数据库操作的效率。原创 2020-11-06 10:46:42 · 322 阅读 · 1 评论 -
Beego框架实战教程:程序执行流程分析
而在routers包前面,可以看到有一个“_”,这表明是引入routers包,并执行init方法。在get函数里面,有三句代码,前两句c.Data[]= ""表示设置返回的数据字段及内容,最后一句c.TplName表示设置处理该请求指向某个模板文件,这里指向了index.tpl,那么index.tpl文件在哪里呢?,这是一个get请求,请求到了后台以后,什么请求参数都没有,因此,就会被“/”拦截,执行到MainController中的代码,因为是get请求,所以这里自动找到Get函数并进行执行。原创 2020-11-10 11:14:00 · 328 阅读 · 0 评论 -
Beego框架实战教程:项目搭建及注册用户
然后设计一下数据表,我们需要用户的id,并且作为主键,用户名username和密码password,还有状态status,这个用于标记该用户是否被删除,0表示正常状态,1表示删除。思路就是先接收表单信息,然后判断数据库中是否已经存在了该用户名,如果已经存在,那么无法进行注册,我们可以通过json返回信息:用户名已经存在。我们先创建一个工具包utils,然后创建一个go文件,用于做mysql的工具类,里面提供连接数据库和创建表的功能。我们可以看到,项目已经运行了,并且监听在8080的端口上。原创 2020-11-11 15:44:30 · 1539 阅读 · 0 评论 -
Beego框架实战教程:数据库配置及连接
以上mysql数据操作都是命令行终端形式,为了方便我们日常操作,我们可以使用图形化界面工具,在这里我们使用的是navicat工具。安装完毕后,将mysql的bin目录路径添加配置到环境变量,以便能够在终端命令行中进行使用登陆mysql。选择下载安装文件,并在本地进行安装。安装过程中,若出现初始密码,要记住该密码,首次登陆时要使用。在上面的链接中,选择自己的系统版本,然后下载安装文件,进行安装,一直默认选下一步即可,最后安装成功。为了使用自己的密码,可以自己设置一个自己熟悉的密码,方便自己记忆。原创 2020-11-11 15:44:59 · 1161 阅读 · 1 评论 -
GO语言:关闭通道和通道上范围循环
在上面的程序中,send Goroutine将0到9写入chl通道,然后关闭通道。如果ok是假的,则意味着通道关闭,因此循环结束。在上面的语句中,如果ok的值是true,表示成功的从通道中读取了一个数据value。从闭通道读取的值将是通道类型的零值。我们可以循环从通道上获取数据,直到通道关闭。for循环的for range形式可用于从通道接收值,直到它关闭为止。接收者可以在接收来自通道的数据时使用额外的变量来检查通道是否已经关闭。例如,如果通道是一个int通道,那么从封闭通道接收的值将为0。原创 2020-11-13 10:52:35 · 325 阅读 · 0 评论 -
GO语言:channel通道
Go语言中,要传递某个数据给另一个goroutine(协程),可以把这个数据封装成一个对象,然后把这个对象的指针传入某个channel中,另外一个goroutine从这个channel中读出这个指针,并处理其指向的内存对象。Go从语言层面保证同一个时间只有一个goroutine能够访问channel里面的数据,为开发者提供了一种优雅简单的工具,所以Go的做法就是使用channel来通信,通过通信来传递内存数据,使得内存数据在不同的goroutine中传递,而不是使用共享内存来通信。(通道的零值为nil。原创 2020-11-13 10:52:44 · 315 阅读 · 0 评论 -
GO语言:sync包——读写锁
在读写锁管辖的范围内,它允许任意个读操作的同时进行。写锁,如果在添加写锁之前已经有其他的读锁和写锁,则Lock就会阻塞直到该锁可用,为确保该锁最终可用,已阻塞的Lock调用会从获得的锁中排除新的读取锁,即写锁权限高于读锁,有写锁时优先进行写锁定。读写锁的写锁只能锁定一次,解锁前不能多次锁定,读锁可以多次,但读解锁次数最多只能比读锁次数多一次,一般情况下我们不建议读解锁次数多余读锁次数。读锁,当有写锁时,无法加载读锁,当只有读锁或者没有锁时,可以加载读锁,读锁可以加载多个,所以适用于“读多写少”的场景。原创 2020-11-17 14:47:27 · 318 阅读 · 0 评论 -
GO语言:sync包——互斥锁
Mutex 是最简单的一种锁类型,互斥锁,同时也比较暴力,当一个 goroutine 获得了 Mutex 后,其他 goroutine 就只能乖乖等到这个 goroutine 释放该 Mutex。在使用互斥锁时,一定要注意:对资源操作完成后,一定要解锁,否则会出现流程执行异常,死锁等问题。就是某个协程(线程)在访问某个资源时先锁住,防止其它协程的访问,等访问完毕解锁后其他协程再来加锁进行访问。每个资源都对应于一个可称为 “互斥锁” 的标记,这个标记用来保证在任意时刻,只能有一个协程(线程)访问该资源。原创 2020-11-17 14:47:43 · 441 阅读 · 0 评论 -
GO语言:临界资源安全问题
我们的卖票逻辑是先判断票数的编号是否为负数,如果大于0,然后我们就进行卖票,只不过在卖票钱先睡眠,然后再卖,假如说此时已经卖票到只剩最后1张了,某一个goroutine持有了CPU的时间片,那么它再片段是否有票的时候,条件是成立的,所以它可以卖票编号为1的最后一张票。其他的第三个第四个goroutine都是这样的逻辑,当某个goroutine醒来的时候,不会再判断是否有票,而是直接售出,这样就卖出最后一张票了,然而其他的goroutine醒来的时候,就会陆续卖出了第0张,-1张,-2张。原创 2020-11-18 16:57:11 · 240 阅读 · 0 评论 -
GO语言:sync包——WaitGroup
我们创建并启动两个goroutine,来打印数字和字母,并在main goroutine中,将这两个子goroutine加入到一个WaitGroup中,同时让main goroutine进入Wait(),让两个子goroutine先执行。当两条子goroutine都执行完毕后,WaitGroup中的counter的数值为零,解除main goroutine的阻塞。如果计数器的数值变为0,那么就表示等待时被阻塞的goroutine都被释放,如果计数器的数值为负数,那么就会引发恐慌,程序就报错了。原创 2020-11-18 16:57:33 · 242 阅读 · 0 评论 -
GO语言:runtime包(文末附:入门基础视频+软件)
尽管 Go 编译器产生的是本地可执行代码,这些代码仍旧运行在 Go 的 runtime(这部分的代码可以在 runtime 包中找到)当中。这个 runtime 类似 Java 和 .NET 语言所用到的虚拟机,它负责管理包括内存分配、垃圾回收(第 10.8 节)、栈处理、goroutine、channel、切片(slice)、map 和反射(reflection)等等。原创 2020-11-20 14:20:59 · 254 阅读 · 0 评论 -
GO语言:Go语言的并发模型
当然在Go的运行时调度器中也有类似的抢占机制,但并不能保证抢占能成功,因为Go运行时系统并没有内核调度器的中断能力,它只能通过向运行时间过长的G中设置抢占flag的方法温柔的让运行的G自己主动让出M的执行权。但这样带来了很多问题,例如,不同的G在不同的M上并发运行时可能都需向系统申请资源(如堆内存),由于资源是全局的,将会由于资源竞争造成很多系统性能损耗,为了解决类似的问题,后面的Go(Go1.1)运行时系统加入了P,让P去管理G对象,M要想运行G必须先与一个P绑定,然后才能运行该P管理的G。原创 2020-11-20 14:21:12 · 204 阅读 · 0 评论 -
GO语言:协程——Goroutine
线程的优点是减小了程序并发执行时的开销,提高了操作系统的并发性能,缺点是线程没有自己的系统资源,只拥有在运行时必不可少的资源,但同一进程的各线程可以共享进程所拥有的系统资源,如果把进程比作一个车间,那么线程就好比是车间里面的工人。进程进程是一个程序在一个数据集中的一次动态执行过程,可以简单理解为“正在执行的程序”,它是CPU资源分配和调度的独立单位。进程控制块用来记录进程的外部特征,描述进程的执行变化过程,系统可以利用它来控制和管理进程,它是系统感知进程存在的唯一标志。随后,这个go程序的运行也会终止。原创 2020-12-02 15:44:04 · 267 阅读 · 1 评论 -
GO语言:遍历文件夹
学习io之后,尤其是文件操作,我们就可以遍历给定的目录文件夹了。可以使用ioutil包下的readDir()方法,这个方法可以获取指定目录下的内容,返回文件和子目录。因为文件夹下还有子文件夹,而ioutil包的ReadDir()只能获取一层目录,所以我们需要自己去设计算法来实现,最容易实现的思路就是使用递归。原创 2020-12-02 15:44:26 · 1019 阅读 · 1 评论