什么是微服务
微服务是一种软件架构风格,它将一个大型应用程序拆分成多个小型的、独立部署的服务,每个服务实现单一业务功能。每个服务运行在自己的进程中,并通过轻量级的通信机制(通常是HTTP RESTful API)相互协作。
微服务的主要特点
- 独立部署:每个微服务都可以独立部署和更新,而无需重新部署整个应用程序。这提高了灵活性和响应速度。
- 模块化:每个微服务只关注一个特定的业务功能或领域(如用户管理、订单处理、支付服务等),这有助于代码的模块化和清晰性。
- 技术多样性:不同的微服务可以使用不同的编程语言、框架和技术栈,根据各自的需求进行选择,允许团队选择最适合的问题域的技术。
- 分布式系统:微服务架构是一个分布式系统,服务之间通过网络进行通信,这意味着需要处理分布式系统的一些挑战,如服务发现、负载均衡、分布式事务等。
- 自治性:每个微服务团队可以自主开发、测试、部署和维护他们的服务,这提高了开发团队的独立性和效率。
微服务的优势
- 灵活性和可伸缩性:微服务可以独立扩展,根据需求增加或减少资源,从而提高系统的可伸缩性和弹性。
- 快速迭代和部署:由于每个微服务可以独立部署,开发团队可以更快地迭代和发布新功能。
- 技术栈灵活性:不同的微服务可以使用不同的技术栈,这允许团队根据具体的需求选择最合适的工具和框架。
- 故障隔离:如果一个微服务出现故障,通常不会影响整个系统,这提高了系统的可靠性和稳定性。
微服务的挑战
- 分布式系统复杂性:微服务架构引入了分布式系统的复杂性,需要处理服务发现、负载均衡、分布式事务、网络延迟、数据一致性等问题。
- 运维复杂性:管理和监控大量微服务的运维工作比单体应用更复杂,需要良好的监控、日志和自动化运维工具。
- 数据管理:在微服务架构中,每个服务通常有自己的数据库,这可能导致数据一致性问题,需要使用分布式数据管理策略。
- 服务间通信:服务间的通信通常使用轻量级协议(如HTTP/REST、gRPC),需要处理通信延迟、超时和失败重试等问题。
微服务与单体架构的对比
- 单体架构:所有功能模块打包成一个整体应用程序,部署和管理较为简单,但随着应用规模增大,开发、测试和部署变得越来越困难。
- 微服务架构:将应用程序拆分成多个小服务,每个服务独立部署和管理,具有更好的灵活性和可伸缩性,但运维和管理复杂性更高。
总之我们应该知道微服务的优点:
- 独立部署:每个微服务可以独立开发、测试、部署和更新,无需影响其他服务。这提高了开发和部署的灵活性,加快了交付速度。
- 技术多样性:不同的微服务可以使用不同的编程语言、框架和技术栈,团队可以选择最适合的技术来实现各自的服务功能。
- 可伸缩性:微服务可以根据需求独立伸缩,优化资源利用。例如,可以单独扩展某个热点服务,而无需扩展整个应用程序。
- 故障隔离:由于微服务是独立运行的,一个服务的故障通常不会影响到其他服务,从而提高了系统的可靠性和稳定性。
- 模块化:每个微服务专注于实现特定的业务功能,使得代码库更清晰、模块化,有助于提高代码的可维护性和可理解性。
- 快速迭代:团队可以独立开发和部署各自的服务,减少了开发的瓶颈和依赖,能够更快地响应业务需求,进行快速迭代。
- 灵活性:微服务架构允许不同团队独立工作,减少了团队之间的依赖关系,提升了开发的灵活性和自主性。
既然有这么多优点,那么肯定会有代价:
比如说:
服务与服务间通信怎么解决?
怎么找到每一个服务的地址?
其实一个项目并不是无脑go-zero的,分布式框架的代码量很大,重复代码也很多,对于简单项目来说,使用go-zero反而是负担。
go-zero框架环境的安装
goctl
若想用go-zero框架,还需要一些前置条件:
安装goctl
go install github.com/zeromicro/go-zero/tools/goctl@latest
可以使用 goctl 命令查看是否安装成功
成功后安装proto
goctl env check --install --verbose --force
然后下载go-zero库,新建一个go项目,运行:
go get -u github.com/zeromicro/go-zero@latest
1.在根目录下创建一个user包
2.在其中,创建一个api服务:
goctl api new api
3.在其中创建一个rpc服务
goctl rpc new rpc
4.在user/api/logic/apilogic下,增加
func (l *ApiLogic) Api(req *types.Request) (resp *types.Response, err error) {// todo: add your logic here and delete this linereturn &types.Response{Message: "hello world"}, nil
}
5.在user的api目录下运行
go run api.go
6.进入http://127.0.0.1:8888/from/me 就可以看到
这样一个简单的项目就跑起来了。
至于为什么需要创建两个服务呢?
API 包用于对外提供 HTTP 接口,适合前端与后端交互;RPC 包用于后端服务之间的高效通信,适合内部服务调用。
API 包:
- 实现对外提供的 RESTful API 接口。例如,用户登录、获取商品列表等。
- 接受前端发来的 HTTP 请求,进行处理后返回 JSON 格式的响应。
RPC 包:
- 实现服务间的 RPC 调用接口。例如,用户服务需要调用订单服务获取订单详情。
- 使用 gRPC 框架进行通信,提供高效的二进制协议数据传输。
总之,这样设计有助于清晰地分离对外接口与内部服务,提升系统的可维护性和可扩展性。
etcd
etcd 是一个分布式键值存储系统,旨在提供一致性、高可用性和可靠的分布式协调。
和redis很像,都是键值对数据库。
但etcd更加专精于强一致性:etcd 使用 Raft 共识算法**,确保了在分布式环境中的强一致性**。这对于服务发现和配置管理等关键任务尤为重要,因为它能确保每个节点都能看到相同的配置和服务状态。
并且etcd本身为分布式系统设计,提供了原生的服务发现和配置管理功能,支持 Watch 机制,可以实时监控配置变化。
etcd 提供了简单且高效的分布式锁实现,适合用于分布式环境中的资源竞争管理。
综上几点,就已经可以说明分布式系统使用etcd存储配置信息的原因了。
再举个例子:正常项目中配置文件写在代码中,若配置文件修改,项目就该重新启动,但是若使用了etcd,每次去查看对应RPC的配置信息时都是从etcd中实时获取。
etcd安装方法:
windows:https://github.com/etcd-io/etcd/releases
去github下载最新版安装包
然后解压,将根文件夹位置添加到环境变量中
之后打开一个命令行窗口,输入:etcd就可以启动了,然后再打开一个黑窗口(上一个不要关)
输入一些简单命令就可以测试etcd的功能了:
linux,使用docker下载最新版:
docker pull quay.io/coreos/etcd:latest
运行etcd容器:
docker run -d \--name etcd-server \-p 2379:2379 \-p 2380:2380 \-v /path/to/etcd-data:/etcd-data \quay.io/coreos/etcd:latest \/usr/local/bin/etcd \--data-dir=/etcd-data \--name my-etcd \--initial-advertise-peer-urls http://0.0.0.0:2380 \--listen-peer-urls http://0.0.0.0:2380 \--advertise-client-urls http://0.0.0.0:2379 \--listen-client-urls http://0.0.0.0:2379 \--initial-cluster my-etcd=http://0.0.0.0:2380 \--initial-cluster-token my-etcd-token \--initial-cluster-state new
验证是否成功安装:
docker exec -it etcd-server shetcdctl --endpoints=http://127.0.0.1:2379 put foo "Hello, etcd"
etcdctl --endpoints=http://127.0.0.1:2379 get foo
成功会看到:
OK
Hello, etcd
goland开发插件
全部安装完成后就可以实现go-zero项目的生成了,但是没有快捷生成proto文件的方法,所以我们需要下载一个插件
这个插件,完成后重启,再新建文件
就能看到api文件和proto文件了,并且该插件还支持对这两种文件的高亮表示,非常方便。
若是还没有,按如下步骤
解决。