用户您好!请先登录!

微服务注册中心的原理及Go的基本实现

在现实生活中,我们每个家庭都有一个户口本,我们会统一的去户籍中心,去注册自己家的信息,包括自己家的门牌号,家里几个人,如果有人找我们,就可以通过这个来定位,同理微服务中的注册中心也是一样,所有的服务实例都到注册中心去注册,后续大家如果需要查找别的服务,就到注册中心去查找即可

服务调用方式

图解微服务注册中心设计原理与思考并基于go语言实现核心架构

服务调用方式主要是指微服务中服务之间调用的方式,主要分为两类:

  • 基于负载均衡:通过负载均衡设备对外提供VIP地址来实现服务的调用
  • 基于注册中心:微服务之间通过服务注册中心进行节点发现,然后在服务端直接调用对应的节点进行调用

阅读更多

10 open source projects proving the power of Google Go

Now 10 years in the wild, Google’s Go programming language has certainly made a name for itself. Lightweight and quick to compile, Go has stirred significant interest due to its generous libraries and abstractions that ease the development of concurrent and distributed (read: cloud) applications.

But the true measure of success of any programming language is the projects that developers create with it. Go has proven itself as a first choice for fast development of network services, software infrastructure projects, and compact and powerful tools of all kinds.

阅读更多

Reference: Uber Go Style Guide

Introduction

Styles are the conventions that govern our code. The term style is a bit of a misnomer, since these conventions cover far more than just source file formatting—gofmt handles that for us.

The goal of this guide is to manage this complexity by describing in detail the Dos and Don’ts of writing Go code at Uber. These rules exist to keep the code base manageable while still allowing engineers to use Go language features productively.

This guide was originally created by Prashant Varanasi and Simon Newton as a way to bring some colleagues up to speed with using Go. Over the years it has been amended based on feedback from others.

阅读更多

Full Link Tracking Learning for Go Microservices

在微服务架构中,调用链是漫长而复杂的,要了解其中的每个环节及其性能,你需要全链路跟踪。 它的原理很简单,你可以在每个请求开始时生成一个唯一的ID,并将其传递到整个调用链。 该ID称为CorrelationID,你可以用它来跟踪整个请求并获得各个调用环节的性能指标。简单来说有两个问题需要解决。第一,如何在应用程序内部传递ID; 第二,当你需要调用另一个微服务时,如何通过网络传递ID。

什么是OpenTracing?

现在有许多开源的分布式跟踪库可供选择,其中最受欢迎的库可能是ZipkinJaeger。 选择哪个是一个令人头疼的问题,因为你现在可以选择最受欢迎的一个,但是如果以后有一个更好的出现呢?OpenTracing可以帮你解决这个问题。它建立了一套跟踪库的通用接口,这样你的程序只需要调用这些接口而不被具体的跟踪库绑定,将来可以切换到不同的跟踪库而无需更改代码。Zipkin和Jaeger都支持OpenTracing。

阅读更多

Istio的分层架构

Istio是ServiceMesh的产品化落地:

  1. 它帮助微服务之间建立连接,帮助研发团队更好的管理与监控微服务,并使得系统架构更加安全
  2. 帮助微服务分层解耦,解耦后的proxy层能够更加专注于提供基础架构能力,例如:
    • 服务发现(discovery)
    • 负载均衡(load balancing)
    • 故障恢复(failure recovery)
    • 服务度量(metrics)
    • 服务监控(monitoring)
    • A/B测试(A/B testing)
    • 灰度发布(canary rollouts)
    • 限流限速(rate limiting)
    • 访问控制(access control)
    • 身份认证(end-to-end authentication) 等功能。
  3. 它使得业务工程团队与基础架构团队都更加高效的工作,各自专注于自己的工作,更好的彼此赋能

今天来说一下Istio的核心架构设计

阅读更多

Gin Web Framework

Gin是一个用Go(Golang)编写的Web框架。它具有类似马提尼的API,具有更好的性能,由于httprouter,速度提高了40倍。

如果你需要表现和良好的生产力,you will love Gin

安装

要安装Gin软件包,您需要先安装Go并设置Go工作区。

  1. 首先需要Go安装(需要1.10+版本),然后你可以使用下面的Go命令来安装Gin。
$ go get -u github.com/gin-gonic/gin

在您的代码中导入它:

阅读更多

ETCD 简介及使用场景

随着CoreOS和Kubernetes等项目在开源社区日益火热,它们项目中都用到的etcd组件作为一个高可用强一致性的服务发现存储仓库,渐渐为开发人员所关注。在云计算时代,如何让服务快速透明地接入到计算集群中,如何让共享配置信息快速被集群中的所有机器发现,更为重要的是,如何构建这样一套高可用、安全、易于部署以及响应快速的服务集群,已经成为了迫切需要解决的问题。etcd为解决这类问题带来了福音,本文将从etcd的应用场景开始,深入解读etcd的实现方式,以供开发者们更为充分地享用etcd所带来的便利。

经典应用场景

要问etcd是什么?很多人第一反应可能是一个键值存储仓库,却没有重视官方定义的后半句,用于配置共享和服务发现。

A highly-available key value store for shared configuration and service discovery.

实际上,etcd作为一个受到ZooKeeper与doozer启发而催生的项目,除了拥有与之类似的功能外,更专注于以下四点。

阅读更多

协程的Golang语言实现

感谢那些开源的贡献者们,使我们可以更深入地了解语言与技术的本质与内部机理。对于Golang语言来说,其最大的特色可以说是协程(goroutine)了, 协程让本来很复杂的异步编程变得简单, 让程序员不再需要面对回调地狱,

虽然现在引入了协程的语言越来越多, 但go中的协程仍然是实现的是最彻底的.

这篇文章将通过分析golang的源代码来讲解协程的实现原理.

这个系列分析的golang源代码是Google官方的实现的1.9.2版本, 不适用于其他版本和gccgo等其他实现, 运行环境是Ubuntu 16.04 LTS 64bit.

核心概念

要理解协程的实现, 首先需要了解go中的三个非常重要的概念, 它们分别是GMP,

没有看过golang源代码的可能会对它们感到陌生, 这三项是协程最主要的组成部分, 它们在golang的源代码中无处不在.

G (goroutine)

G是goroutine的头文字, goroutine可以解释为受管理的轻量线程, goroutine使用go关键词创建.

举例来说, func main() { go other() }, 这段代码创建了两个goroutine,

一个是main, 另一个是other, 注意main本身也是一个goroutine.

goroutine的新建, 休眠, 恢复, 停止都受到go运行时的管理.

goroutine执行异步操作时会进入休眠状态, 待操作完成后再恢复, 无需占用系统线程,

goroutine新建或恢复时会添加到运行队列, 等待M取出并运行.

M (machine)

M是machine的头文字, 在当前版本的golang中等同于系统线程.

M可以运行两种代码:

  • go代码, 即goroutine, M运行go代码需要一个P
  • 原生代码, 例如阻塞的syscall, M运行原生代码不需要P

M会从运行队列中取出G, 然后运行G, 如果G运行完毕或者进入休眠状态, 则从运行队列中取出下一个G运行, 周而复始.

有时候G需要调用一些无法避免阻塞的原生代码, 这时M会释放持有的P并进入阻塞状态, 其他M会取得这个P并继续运行队列中的G.

go需要保证有足够的M可以运行G, 不让CPU闲着, 也需要保证M的数量不能过多.

P (process)

P是process的头文字, 代表M运行G所需要的资源.

一些讲解协程的文章把P理解为cpu核心, 其实这是错误的.

虽然P的数量默认等于cpu核心数, 但可以通过环境变量GOMAXPROC修改, 在实际运行时P跟cpu核心并无任何关联.

P也可以理解为控制go代码的并行度的机制,

如果P的数量等于1, 代表当前最多只能有一个线程(M)执行go代码,

如果P的数量等于2, 代表当前最多只能有两个线程(M)执行go代码.

执行原生代码的线程数量不受P控制.

因为同一时间只有一个线程(M)可以拥有P, P中的数据都是锁自由(lock free)的, 读写这些数据的效率会非常的高.

阅读更多

WebSocket的高性能实现(Go and Netty)

WebSocket是HTML5开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。在WebSocket API中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。浏览器通过 JavaScript 向服务器发出建立 WebSocket 连接的请求,连接建立以后,客户端和服务器端就可以通过 TCP 连接直接交换数据。当你获取 Web Socket 连接后,你可以通过 send() 方法来向服务器发送数据,并通过 onmessage 事件来接收服务器返回的数据。

WebSocket的优点

  • 节省通信开销(HttpRequest中的head很长,占用带宽和资源)
  • 服务器可以主动传送数据给客户端
  • 实时通信
    因为HTTP 协议是一种无状态的、无连接的、单向的应用层协议。它采用了请求/响应模型。通信请求只能由客户端发起,服务端对请求做出应答处理。这种通信模型有一个弊端:HTTP 协议无法实现服务器主动向客户端发起消息。如果服务器有连续的状态变化,客户端要获知就非常麻烦。大多数 Web 应用程序将通过频繁的异步JavaScript和XML(AJAX)请求实现长轮询。轮询的效率低,非常浪费资源(因为必须不停连接,或者 HTTP 连接始终打开)。

WebSocket的生命周期

WebSocket端点生命周期的第一个事件是打开通知,它用来指示到WebSocket会话另一端的连接已经建立。一旦打开通知被WebSocket对话的两端都接收到,参与的任意WebSocket后续就可以发送消息了。在WebSocket对话期间,可能会出现一些消息传递的错误。接受消息的WebSocket端点本身就可能产生错误,或者WebSocket实现本身在某些情况下也会产生错误。要注意对错误的处理。不管在WebSocket对话的哪一端准备结束对话,他都可以初始化关闭事件。下面从Java组件的视角来看看其生命周期如何呈现。

  • 打开事件:@OnOpen 此事件发生在端点上建立新连接时并且在任何其他事件发生之前
  • 消息事件:@OnMessage 此事件接收WebSocket对话中另一端发送的消息。
  • 错误事件:@OnError 此事件在WebSocket连接或者端点发生错误时产生
  • 关闭事件:@OnClose 此事件表示WebSocket端点的连接目前部分地关闭,它可以由参与连接的任意一个端点发出

阅读更多