开篇
当越来越多的公司和项目拥抱微服务,总会有人会不自觉的掉入微服务的坑中。微服务虽然是解决大部分服务性能问题的一剂良药,但却不是唯一的选择,有时候或许还不是最佳的选择。例如当甲方是一个除了钱什么都缺,尤其是缺维护人员的公司。那么在给对方提供数据库性能优化方案的时候,那么选择Oracle就比MySQL集群更能药到病除。所以微服务只是系统自我演进过程中未来的一种可能发展方向,并不是一种为了炫耀技术的手段,除非炫耀技术本身会为公司带来丰厚的利润。
一个能够支撑产品快速迭代开发并响应市场需求的架构才是一个好架构,如果当一个产品的业务开发人员有一半以上的开发时间都花费在架构的适配上,那么整套架构的价值又体现在什么地方。
一个好的架构不是设计出来的,而是随着业务的增长一步一步演进而来的。如果试图在产品的一开始就采用微服务的架构,那么请自问是否做好接受微服务中的伤与痛。
楔子
微服务有着许多被人们津津乐道的优点,无论是在博客,论坛还是技术沙龙上面都被人们所传唱。就像是再富丽堂皇的宫殿也有污秽的下水道一样,微服务也有着许多的坑等着前赴后继的人们去趟,技术好的人或许能够很快的过去,技术不好的人就只能望而却步。
在本系列中,我们将从小码农的视角来看看微服务的那些坑。现阶段小码农遇到的坑主要有以下几部分
- 微服务中的耦合问题
- 微服务中的分布式事务问题
- 微服务中的统一日志问题
- 微服务中的监控问题
- 微服务中的服务合并问题
后面我们会一一聊聊这些问题,并探讨一些可能的解决方案。
为了探讨以上问题,就需要我们先搭建一个简单的微服务架构。这里我们使用Zookeeper作为服务的注册中心,负责服务的动态发现。各服务模块之间采用gRPC作为服务的通讯方式。而微服务中的其他组成部分我们会在后续章节中逐步完善。
在本篇中我们首先介绍一下Google所推出的RPC产品gRPC。
正文
简介
gRPC是Google开源的一款高性能RPC框架。采用IDL(Interface Description Language )来定义客户端与服务端进行通信的数据结构和接口,然后再编译成为指定语言版本的数据与接口代码。
gRPC使用Protocol Buffers作为 IDL 和底层的序列化工具。Protocol Buffers 也是非常有名的开源项目,主要用于结构化数据的序列化和反序列化。当前gRPC推荐使用的语法是proto3。
IDL
下面我们将通过一个例子来简单介绍一下proto3的语法,在本文中我们使用的语言为Java,我们定义了一个接口sayHello
和两个模型对象HelloRequest
和HelloResponse
entity.proto
// 声明protobuf版本为proto3
syntax = "proto3";
// 使用package避免命名冲突
// package默认会作为java的包名
package org.sydonay.demo.rpc;
// 如果为true时message会生成多个类
option java_multiple_files = true;
// 如果使用option java_package的话则会被优先设置为包名
option java_package = "org.sydonay.demo.model";
// 指定生成Java的类名,如果没有该字段则根据proto文件名称以驼峰的形式生成类名
option java_outer_classname = "Hello";
message HelloRequest {
string name = 1;
}
message HelloResponse {
string echo = 1;
}
interface.proto
syntax = "proto3";
package org.sydonay.demo.rpc;
option java_multiple_files = true;
option java_package = "org.sydonay.demo.service";
option java_outer_classname = "HelloInterface";
// 导入其他proto文件中声明的类型
import "entity.proto";
service HelloService {
// protocol buffers 的 idl中不允许无参函数的定义,如果业务有需要可以定义一个空message
// 接口不支持基本类型,必须将入参和出参定义为message类型
rpc sayHello(HelloRequest) returns (HelloResponse);
}
在这里我们可以看到这两个idl文件的后缀名都是proto,为了将这两个文件编译成为代码,我们需要借助两个工具protoc.exe
和protoc-gen-grpc-java.exe
。
1、protoc.exe
下载地址:https://github.com/google/protobuf/releases
功能:用来生成消息对象等代码
编译命令:
protoc.exe --java_out=./ filename.proto
2、protoc-gen-grpc-java.exe
下载地址:https://github.com/grpc/grpc-java/tree/master/compiler,这个需要自行进行编译
功能:用来生成rpc通讯相关代码
编译命令:
protoc.exe --plugin=protoc-g