微服务架构是一种设计方法,而微服务这是应该指使用这种方法而设计的一个应用。所以我们必要对微服务的概念做出一个比较明确的定义。
微服务框架是将复杂的系统使用组件化的方式进行拆分,并使用轻量级通讯方式进行整合的一种设计方法。
微服务是通过这种架构设计方法拆分出来的一个独立的组件化的小应用。
微服务架构定义的精髓,可以用一句话来描述,那就是“分而治之,合而用之”。
将复杂的系统进行拆分的方法,就是“分而治之”。分而治之,可以让复杂的事情变的简单,这很符合我们平时处理问题的方法。
使用轻量级通讯等方式进行整合的设计,就是“合而用之”的方法,合而用之可以让微小的力量变动强大。
三层架构(MVC)
的具体内容如下:
表示层(view): 用户使用应用程序时,看到的、听见的、输入的或者交互的部分。
业务逻辑层(controller): 根据用户输入的信息,进行逻辑计算或者业务处理的部分。
数据访问层(model): 关注有效地操作原始数据的部分,如将数据存储到存储介质(如数据库、文件系统)及从存储介质中读取数据等。
虽然现在程序被分成了三层,但只是逻辑上的分层,并不是物理上的分层。也就是说,对不同层的代码而言,经过编译、打包和部署后,所有的代码最终还是运行在同一个进程中。而这,就是所谓的单块架构。
单体架构在规模比较小的情况下工作情况良好,但是随着系统规模的扩大,它暴露出来的问题也越来越多,主要有以下几点:
复杂性逐渐变高
比如有的项目有几十万行代码,各个模块之间区别比较模糊,逻辑比较混乱,代码越多复杂性越高,越难解决遇到的问题。
技术债务逐渐上升公司的人员流动是再正常不过的事情,有的员工在离职之前,疏于代码质量的自我管束,导致留下来很多坑,由于单体项目代码量庞大的惊人,留下的坑很难被发觉,这就给新来的员工带来很大的烦恼,人员流动越大所留下的坑越多,也就是所谓的技术债务越来越多。
维护成本大
当应用程序的功能越来越多、团队越来越大时,沟通成本、管理成本显著增加。当出现 bug 时,可能引起 bug 的
原因组合越来越多,导致分析、定位和修复的成本增加;并且在对全局功能缺乏深度理解的情况下,容易在修复
bug 时引入新的 bug。
持续交付周期长
构建和部署时间会随着功能的增多而增加,任何细微的修改都会触发部署流水线。新人培养周期长:新成员了解背景、熟悉业务和配置环境的时间越来越长。
技术选型成本高
单块架构倾向于采用统一的技术平台或方案来解决所有问题,如果后续想引入新的技术或框架,成本和风险都很大。
可扩展性差
随着功能的增加,垂直扩展的成本将会越来越大;而对于水平扩展而言,因为所有代码都运行在同一个进程,没办法做到针对应用程序的部分功能做独立的扩展。
例如:
syntax = "proto3";message HelloRequest {
string name = 1;
}
message HelloResponse {
string greeting = 2;
}
service Greeter {
rpc Hello(HelloRequest) returns (HelloResponse) {}
}
服务端
type Greeter struct {}
func (g*Greeter)Hello(ctx context.Context, rep *pb.HelloRequest, rsp *pb.HelloResponse) error {
rsp.Greeting="Hello"+rep.Name
return nil
}
func main() {
service := micro.NewService(
micro.Name("greeter"),
micro.Metadata(map[string]string{"type": "hello"}),
micro.Version("1.1"),
)
service.Init()
pb.RegisterGreeterHandler(service.Server(),new(Greeter))
service.Run()
}
客户端
func main() {service := micro.NewService(
micro.Name("a"),
micro.Metadata(map[string]string{"type": "hello"}),
micro.Version("1.1"),
)
service.Init()
greeterService := pb.NewGreeterService("greeter", service.Client())
req := pb.HelloRequest{}
req.Name="wilsona"
response, e := greeterService.Hello(context.TODO(), &req)
fmt.Println(response.Greeting,e)
}