当前位置: 首页 > news >正文

k8s部署前后分离架构微服务——跨域和缓存问题

前面k8s环境部署的差不多了,现在尝试把自己开发的微服无程序部署到k8s环境中。

首先是打包镜像,前端是用了Ant Design Vue Pro框架开发的,使用cnpm run build 编译,会在工程目录下生成一个dist文件目录,再将此目录和nginx打包为docker镜像,上传到私有harbor仓库中就可以进行k8s的部署了。

1.我这里前端的镜像和要调用api服务不在同一个pod下,就遇到了CORS(跨域资源共享)问题,前端是禁止跳转访问api的服务的,即便在api服务上做了类似下面的cors设置也还是解决不了问题。

//go代码 中间件设置
handlers.CORS(handlers.AllowedHeaders([]string{"X-Requested-With", "Content-Type", "Authorization", "Kt"}), //这里需要添加自定义的头部信息如Kthandlers.AllowedMethods([]string{"GET", "POST", "HEAD", "OPTIONS", "PUT", "DELETE"}),handlers.AllowedOrigins([]string{"*"}),handlers.AllowCredentials(), // 允许携带凭证(如 cookies))

问了deepseek,我采用了使用nginx代理方案。即在Ant Design Vue Pro框架的工程目录下有deploy/nginx.conf的配置文件,将其配置文件的注释部分打开,设置代理跳转地址,为了方便过滤需要跳转的url,我在.env文件中VUE_APP_API_BASE_URL=/api统一为跳转的url添加了一个/api/ 前缀,这样在nginx代理时,就会将所有有/api/前缀的url拦截,进入代理步骤,当然你的前缀也可以自定义,只要和nginx.conf配置文件中过滤的前缀设置一致就行,如下

  location /api/ {proxy_pass http://roles-manage.eqim.svc.cluster.local:8002/;  #这是需要跳转的地址proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;}
}
# 跳转的时候,将/api/前缀自动去除。

这样再重新编译工程,打包前端镜像,部署后,cors跨域问题就可以解决了。

2. 遇到的第二个问题是缓存问题。之前api服务使用单个redis测试开发的,现在k8s环境中部署的是redis集群,它和单个redis部署的不同点是:在写入和读取时,数据是通过hash分片保存到某一个集群的pod节点上,但为服务的pod此时要访问的redis的pod不一定是存储数据的pod,这样redis集群会发出重定向指令,但是正常使用单个redis测试开发的服务程序是不支持这个重定向的,就会出现,写入的数据获取失败的问题。一开始想通过不修改代码的方式解决,于是选择部署一个redis-cluster-proxy代理服务,应用服务连接代理服务,由代理服务协调redis集群的读写问题。方案是可行的,但我没有搞成功。原因是我没找到现成的redis-cluster-proxy的镜像,是通过下载源码编译自己打包的镜像,不知是什么原因,每次连接代理服务的pod总重启,导致没法使用。

于是我只好退回来选择修改代码的方式来解决缓存问题。

这里也遇到点坑,就是github.com/go-redis/redis/v8 库不支持域名或ip地址的问题,好像只支持类似localhost或主机名的地址方式,不适合在k8s中使用,经过多次尝试,我换了github.com/redis/go-redis/v9库,官网地址

修改代码只需要修改连接redis的代码部分就行,后面的读写操作代码不用修改。代码修改类似下面所示:

// go语言代码//config中的c.Redis.Addr设置:redis-cluster-0.redis-headless.redis.svc.cluster.local:6379,redis-cluster-1.redis-headless.redis.svc.cluster.local:6379,redis-cluster-2.redis-headless.redis.svc.cluster.local:6379var (rdb           redis.CmdablesingleClient  *redis.ClientclusterClient *redis.ClusterClient)redis_addr := strings.Split(c.Redis.Addr, ",")redis_addr_num := len(redis_addr)if redis_addr_num == 0 {panic("redis连接失败!!!\n 请检查配置地址信息。")}if redis_addr_num == 1 {singleClient = redis.NewClient(&redis.Options{Addr:         redis_addr[0],Password:     c.Redis.Passwd,DialTimeout:  c.Redis.DialTimeout.AsDuration(),WriteTimeout: c.Redis.WriteTimeout.AsDuration(),ReadTimeout:  c.Redis.ReadTimeout.AsDuration(),})err = redisotel.InstrumentTracing(singleClient)if err != nil {log.Fatal(err)}rdb = singleClient}if redis_addr_num > 1 {clusterClient = redis.NewClusterClient(&redis.ClusterOptions{Addrs:        redis_addr,Password:     c.Redis.Passwd,DialTimeout:  c.Redis.DialTimeout.AsDuration(),WriteTimeout: c.Redis.WriteTimeout.AsDuration(),ReadTimeout:  c.Redis.ReadTimeout.AsDuration(),})//log.Info(fmt.Printf("redis集群地址:%v \n", clusterClient.ClientList(context.Background())))//log.Info(fmt.Printf("redis集群信息:%v \n", clusterClient.ClusterInfo(context.Background())))// 添加集群健康检查ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)defer cancel()log.Info("执行Redis集群Ping测试...")if err := clusterClient.Ping(ctx).Err(); err != nil {log.Fatal("Redis集群连接失败: %v", err)// 可以在这里降级到单节点模式或抛出更明确的错误} else {log.Info("Redis集群连接成功")}err = redisotel.InstrumentTracing(clusterClient)if err != nil {log.Fatal(err)}rdb = clusterClient}......defer func() {if singleClient != nil {err := singleClient.Close()if err != nil {log.Error(err)}}if clusterClient != nil {err := clusterClient.Close()if err != nil {log.Error(err)}}
}()

重新编译打包部署,就可以解决redis集群缓存读写数据不一致问题了。

这里的数据库使用的是greatsql, 在MySQL和MariaDB 迁移过程中,遇到的问题不大,大部分是在创建数据表时,字符集和默认数据格式问题,比如在MariaDB 中 datetime类型 的默认值可以设置为‘0000-00-00 00:00:00’ ,而在greatsql中较为严格,只支持'1970-01-01 00:00:00' 格式。建议在迁移数据表的时候,将表结构单独部署,使用sql语句一个表一个表的执行,方便查错。迁移过程中一般情况批量导入都会报错。另外数据库工具也非常关键,目前还是没找到太好用的替代Navicat的工具。使用开源的Dbeaver 有时会出现莫明其妙的数据导入后,应用服务读取数据错误的问题。具体原因还没太搞明白,可能和字符集有关,具体还待进一步研究。

http://www.dtcms.com/a/427330.html

相关文章:

  • 临沂网站建设推荐wordpress 评论倒序
  • MyBatis Plus注解 @TableField
  • 石家庄建设工程招标办网站成都网站推广公司
  • 【C#避坑实战系列文章16】性能优化(CPU / 内存占用过高问题解决)
  • JavaScript性能优化实战:从指标到落地的全链路方案
  • 上海网站优化加盟网站建设的公司开发
  • 网站怎么发布到服务器青岛不错的网站公司
  • linux0.11学习之启动主线要点(一)
  • Invoke-customs are only supported starting with Android O (--min-api 26)
  • 安卓基础组件014--button圆角 背景色 边框
  • 【Android】浅谈kotlin协程应用
  • 比价网站源码整站程序梦幻西游网页版app
  • dz做网站虚拟主机可以干什么
  • Windows10,11自带的Hyper-V虚拟机开启及使用方法
  • QCustomPlot 系列总结:从入门到精通的完整指南与资源整理
  • RK3566鸿蒙开发板规格书Purple Pi OH
  • 大模型落地深水区:企业 AI 转型的实践路径与价值突破
  • 金顺广州外贸网站建设图片模板网站
  • LinuxC++——etcd-cpp-api精简源代码函数参数查询参考
  • [特殊字符]️ Spring Cloud Eureka 三步通:搭建注册中心 + 服务注册 + 服务发现,通俗易懂!
  • 打工人日报#20250930
  • 六安网站建设网络服务中国都在那个网站上做外贸
  • 软件工程实践团队作业——团队组建与实践选题
  • YDWE编辑器系列教程二:物体编辑器
  • 软考-系统架构设计师 NoSQL数据库详细讲解
  • 钢铁厂设备健康监测系统:AIoT技术驱动的智慧运维革命​
  • Elasticsearch集群监控信息(亲测)
  • TARA (威胁分析与风险评估) 学习笔记
  • 网站集成微信登陆如何选择大良网站建设
  • 鸿蒙:使用Image组件展示相册图片或rawfile图片