一、开篇小记
过去的一段时间,一直在赶一些项目的进度,再加上前阵子的封控,一直没有时间静下心来好好整理和总结。从这周开始,总算有时间整理点东西了,就还是继续折腾了一些关于微服务的知识点。
由于我本人呢,也是刚刚才迈进微服务开发的大门,萌新级别,所以有些总结不到位的地方,感谢批评指点。
先决条件
Windows环境
- Docker Desktop
- Kubernetes(单节点测试环境docker desktop会提供,云端标准测试环境或者基于ServerLess的测试环境)
Linux环境
- Docker
- Kubernetes(单节点的测试环境,如minikube,云端标准测试环境或者基于ServerLess的测试环境)
MacOS
- 理论上也是有docker和k8s的测试节点就行,老弟这没Mac机器(但是我好想要~~😭)
开始之前
大家可能也都知道,微服务模式的诞生为我们解决了大流量,高并发等传统开发模式无法解决的问题,但同时也对各类基础设施提出了更高的挑战,所以我在后面要展示的一些案例,即便业务部分非常简单,但配置和部署的流程也会有一点复杂。而关于复杂性的讨论,我会在最后再展开聊。
二、Dapr?
Dapr是一个分布式应用程序运行时(runtime),提供了诸多简化微服务链接的API。无论你的通信模式是服务到服务调用还是发布/订阅消息传递,Dapr 都可以帮助你编写可复原且安全的微服务。 通过让 Dapr 使用挎斗模式(sidecar)处理复杂的挑战,例如服务发现、消息代理集成、加密、可观测性和机密管理,让你可以专注于业务逻辑并保持代码简单。
更多关于Dapr的介绍,看官网吧👉Dapr - Distributed Application Runtime(中文站:Dapr 中国社区)
三、Why Dapr?
一句话概况就是,使用 Dapr,您可以使用任何语言、框架轻松构建微服务应用,运行在任何地方。
再说明白点就是,基于dapr,你的团队,或者公司,用什么开发语言,开发框架,都变得不重要了,格局打开了~
总的来说就是,云原生时代,转型微服务已经有了多种方式,Dapr通过提供运行时的方式,为我们封装好了很多构建块,开箱即用,且都是独立的,可以自由选择使用1个或多个,服务间的通信调用也全部有Dapr来完成而且是使用更高性能的gRPC协议。通过Dapr提供的Sidecar模式,我们可以以一种非常省力甚至于偷懒的方式,把我们的业务系统快速转型成微服务系统中的一环。
更多的,还是推荐看官网的描述👉:Building blocks | Dapr Docs(中文站:概述 | Dapr 文档库)
ps.为啥要看英文版的原网站,绝不是装13,主要有以下两点原因。
- 1是中文站的翻译和原网站不完全是一一对应的,很多知识点你只能在英文站点看到,在翻译软件助力下,理解起来不是很费力;
- 2是学习任何知识,都应该遵循一个基本原则,到知识的源头学习!
四、集成Dapr
1.安装Dapr
安装的流程我在这里也不多说了,官方网站那里有非常详细的安装教程(👉:Getting started with Dapr | Dapr Docs),根据那个一步步来就可以。
需要注意的一点就是,如果使用脚本的形式安装,可能下载文件的时候由于众所周知的原因你的下载会概率性的失败,如果出现这种情况,可以通过官方提供的“Binaries”形式安装,自己去下载安装需要的文件,然后再进行后续的解压,配置操作。Windows环境下,解压到指定目录后在配置到环境变量就可以,Linux/MacOS的就把执行文件移动到/user/local/bin目录下就可以了,或者可以放到任何地方,然后通过alias命令做个软链。
安装完成后,在控制台输入“dapr”,出现下面这个画面就ok了
或者执行
dapr version
查看运行时和cli版本。
然后初始化dapr
dapr init --runtime-version 1.9.1 #指定运行时版本
如果出现下面这个错误👇,就到dapr的仓库地址,把对应版本的文件下载下来自己解压,默认地址是C:\Users\{你的用户名}\.dapr,包含一个dapr和dashboard(可以在本地快速浏览服务节点的情况)的执行文件。
如果安装失败,就执行“dapr uninstall”命令重试一下。
如果下载了dashboard的执行文件,可以打开浏览器,查看基于dapr运行时的应用的状态了。
dapr dashboard -p 9999 #端口号指定一个空闲的就可以,不指定就是默认的8080
2.几个案例
案例其实我也不想说太多,一是因为官方也提供了案例,再有就是我们这边正式的项目也还没有开始向基于dapr的微服务方向转,但总算是有了个比较明确的方向,关于微服务的分享肯定也不是一篇两篇博客就能说清楚的,后续肯定会持续输出。这里就主要聊一下在跑通这些案例的过程中需要注意的地方。
0.开始之前
初始化dapr环境
dapr init --runtime-version 1.9.1
1.在本地跑通的案例
Dapr官方提供了基于诸多开发语言的SDK,包括了DotNet,所以,DotNet开发基于Dapr的应用非常方便。
这里我们先假设一个微服务项目,包含一个前台服务,一个后台服务。
前台服务
- 创建一个前台项目,可以是web,可以是控制台,可以是任何dotnet框架支持的终端格式
- 添加Dapr.Client(for client)或Dapr.AspNetCore(for web)包,我这里就以web为例,可以通过nuget或者命令行执行如下命令
dotnet add package Dapr.AspNetCore
- 修改Program.cs,注入Dapr服务
var builder = WebApplication.CreateBuilder(args);// Add services to the container.
builder.Services.AddDaprClient();
//...
- 修改默认的页面,改为通过dapr sdk获取数据的形式
using Dapr.Client;
using Microsoft.AspNetCore.Mvc.RazorPages;namespace MyFrontEnd.Pages;public class IndexModel : PageModel
{private readonly DaprClient _daprClient;public IndexModel(DaprClient daprClient){_daprClient = daprClient;}public async Task OnGet(){var forecasts = await _daprClient.InvokeMethodAsync<IEnumerable<WeatherForecast>>(HttpMethod.Get,"MyBackEnd",//后台服务的名称,这个要注意!"weatherforecast");ViewData["WeatherForecastData"] = forecasts;}
}
- 修改一下页面,为了展示结果
@page
@model IndexModel
@{ViewData["Title"] = "Home page";
}<div class="text-center">
<h1 class="display-4">Welcome</h1>
<p>Learn about <a href="https://learn.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
@foreach (var forecast in (IEnumerable<WeatherForecast>)ViewData["WeatherForecastData"]!)
{<p>The forecast for @forecast.Date is @forecast.Summary!</p>
}
</div>
后台服务
- 创建一个默认的API项目就可以了,其他不用调整。
添加容器支持
关于添加容器支持的部分,我这里不多说了,就直接过一下流程,至于怎么启动容器,怎么配置等等网上也有很多教程,我在之前的博客里也提到过,可以参考简单👉:把项目打包成docker镜像,并发布到腾讯云?DockerHub!_Dockerhub_为自己带盐_InfoQ写作社区
- 给两个项目都添加docker支持,注意目标OS选Linux
- 创建一个docker-compose项目,编写docker-compose.yaml文件,把我们的服务打包发布到容器当中
version: '3.4'services:myfrontend:image: ${DOCKER_REGISTRY-}myfrontendbuild:context: .dockerfile: MyFrontEnd/Dockerfileports:- "51000:50001"myfrontend-dapr:image: "daprio/daprd:1.9.1" #注意最好天上版本号,和本机开发环境保持一致,下面的同理command: [ "./daprd", "-app-id", "MyFrontEnd", "-app-port", "80" ] #注意这里的app-port参数要和项目对应的dockerfile里指定的端口参数对应depends_on:- myfrontendnetwork_mode: "service:myfrontend"mybackend:image: ${DOCKER_REGISTRY-}mybackendbuild:context: .dockerfile: MyBackEnd/Dockerfileports:- "52000:50001"mybackend-dapr:image: "daprio/daprd:1.9.1"command: [ "./daprd", "-app-id", "MyBackEnd", "-app-port", "80" ]depends_on:- mybackendnetwork_mode: "service:mybackend"
- docker-compose.yaml文件编写完成后,设置docker-compose项目为启动项,就可以看到运行效果了
- 最后,需要提几个主义的点,打包容器的配置文件docker-compose.yaml,要注意一些关键参数,比如,dapr对外提供的rest默认通信端口是3500,如果要修改的话,需要增加参数“--dapr-http-port”,用的是http协议,而服务间的dapr和dapr之间的通信端口是50001,走的是grpc协议。这里,强烈建议看一下官方的这篇介绍👉:Service invocation overview | Dapr Docs
3.在开发环境下的Kubernetes集群上跑通案例(minikube)
要把项目移植到kubenetes集群,对初学者来说其实不是件轻松事。但我们如果要转型到微服务开发,就必须要尝试走通这一步。
环境准备
minikube的官方站点是👉:minikube
根据文档的说明,先完成minikube的安装。这里要说明的是,minikube安装需要docker环境,需要先检查自己的Linux系统或者虚拟机里是否安装了docker。
我这里实际测试了基于CentOS7.9和WSL2两种环境,其中CentOS的话,需要自己参照教程安装一下Docker,WSL2和windows宿主机器共享Docker运行环境,只要安装了Docker Desktop,并配置了下图选项就可以
CentOS安装好Docker后的效果
安装好Docker之后,就可以安装minikube了
- 准备一个非root账号。大概流程如下,但如果遇到一些权限问题,可以自行搜索对应linux发行版的解决办法,总之最后的目的就是不能用root用户来安装minikube,这点和安装一些其他软件如ElasticSearch的原理是一样的。
#1.创建账号
useradd tony #自定义
#2.创建密码
passwd tony #然后根据提示输入密码就好
#3.分到docker用户组(没有就创建一个)
sudo gpasswd -a tony docker
#4.更新docker用户组
newwrp docker
#5.切换到新账号
su tony
- 安装minikube
#下载
sudo curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
#安装
sudo install minikube-linux-amd64 /usr/local/bin/minikube
- 初始化minikube运行环境,需要注意的是,截止到当前,kubernetes最新的版本是1.26.0,但我这里踩过坑了,最新版本的安装会有兼容性问题,这里大家如果想安装新版本的话,会少不了折腾一番,那如果不想折腾的话,建议直接安装1.23.8。另外镜像国家选中国,如下:
minikube start --image-mirror-country='cn' --kubernetes-version=v1.23.8
在CentOS环境的安装效果如下
跑通Hello-K8s
- 前置条件:安装好dapr cli
- 初始化运行环境
dapr init -k
#或者
dapr init --kubernetes --wait
...这里由于放假,没有整理完,先搁置,后续补上!
*4.在基于ServerLess的Kubernetes集群上跑通案例
***这里建议如果有其他云的使用经验,且对腾讯云不熟悉的同学,直接跳过吧~***
上面的Hello-k8s的项目里,官方给的例子是在微软云服务Azure的aks环境执行的情况,我这里改成了腾讯云tke的环境。在国内使用Azure的服务应该是无障碍的,但他那个付款模式我有点摸不透,需要使用visa的信用卡,而且也确实没用过国外厂商的云服务。对腾讯云相对更熟悉一些,这里就以腾讯云为例,简单聊一下,稍后再聊一下基于minikube的
- 开通容器服务:https://console.cloud.tencent.com/tke2/cluster,注意选serverless集群,因为咱就是测试,要为考虑成本!事实上,云原生时代,任何的微服务都应该积极转向serverless模式,标准集群的模式无法完美解决弹性扩容缩容的需求,而且,贼贵!
- 开通外部访问,注意,这一步就开始要收费了奥,但是不贵,按量计费,一小时也就几毛钱,用完了不满意关了就行
- 下载kubeconfig文件到本地
- 修改~/.kube路径下的config文件,我这里因为使用的wsl,所以我就直接把原来的config文件备份了一份,然后直接把新的文件配置设置成默认config了
- 修改之后,如果像我这样操作,那集群上下文就只有一个,执行“kubectl config get-contexts”命令,可以看到如下结果
- 如果你是通过合并云端的kubeconfig,那就需要执行切换上下文的操作
kubectl config use-context cls-n7u1qb85-context-default
- 上述操作完成后,就可以看到我们已经成功连接到腾讯云的k8s集群了
- 后续我这里在写博客的时候因为节点都释放掉了,然后操作的时候也忘记截图了,所以,额...
剩下的操作,就非常简单了,主要的难点就在环境的部署上,大家可以根据这个说明来操作就ok👉:quickstarts/tutorials/hello-kubernetes at master · dapr/quickstarts · GitHub
后记
如果屏幕前的兄弟你,之前没有微服务系统的开发经验,在开始接触这些知识点的时候,难免会有一些心智负担。这点我非常理解,毕竟微服务不是一个简单的开发框架,它还涉及到很多周边知识点,包括但不限于inux内核的操作系统(如CentOS,RedHat),容器(如Docker,Podman),容器编排(如Kubernetes),事件总线,代理,审计,网关,缓存,后台服务等。如果你之前没有过分布式系统的开发经验,只是接触一些Curd,或者聚焦于实现一些定制化的功能,而没有考虑并处理过高并发,大流量等问题,那很可能也就没有全部接触过“微服务”的周边知识。
但如果你说我在小厂,业务量根本就达不到需要把改造成“微服务”体系的程度,所以也就不想投入精力去折腾。那关于这点,让我想起,以前上学的时候,有的村里的大人会说,上半天学有什么用,出来不还是找不到工作。也确实很多人不上学早早的就有了可观的收入,也确实有人念了半辈子书,到头来一事无成。那我们就要放弃上学吗?而且今时不同往日,当今社会,如果还没有学历,没有知识,能选择的路就太少了,也就失去了本该一直存在的激情和热血。
回到开发的角度来说,是一样的,要不要转型,其实很大程度上取决于自己,而不是别人,当你不断地学习微服务相关的知识点时,会不得不去了解这些周边知识,就难免造成主线任务的卡壳,但当我们突破重重关卡,有了一定的积累,转型可能就是一件“自然而然”发生的事情了。
云原生的时代已经到来,用积极的心态去拥抱它吧。