为了账号安全,请及时绑定邮箱和手机立即绑定

不停机图片升级迁移

标签:
Java

在我看来,凡是真实环境需要不停机迁移,其实都是有的复杂的,需要考虑的事情有很多,也可以从重思考到很多,以及以后做类似事情可以提前考虑后期的迁移等事宜。

迁移需求

原来图片服务使用技术为A,随着图片慢慢越来越多,使用的A技术带来的弊端越来越多,后来了解到技术B,技术B目前各各方面都挺好,也满足要求,现在就有一个难题,如何使得目前图片服务由原来的A切换到B呢?由于技术A实现和技术B实现方式区别,图片存储方式都进行了变化,需要进行迁移到B实现方式上面,并且需要做到不间断,持续提供服务。由于真实比较复杂,简单抽象下:

  • 图片具体文件存储在用技术A实现的目录下面。

  • 所有的图片元信息存储在数据库里面。

  • 有N多地方会操作这个元信息表。

  • 很多图片地址可能被收录了。

  • 可能有些手机版本用户没有升级,一直用老版本情况。

需要换一个图片实现技术B,但是上面的这些问题都需要考虑,并且需要做到不间断,持续提供服务。主要使用图片技术B之后图片技术A的图片存放地方变了,导致元信息表里面的某些字段也需要由于技术B的改动而改动。

难点

  1. Java Web技术中有两种跳转,服务端跳转、客户端跳转。

    forward这种它只能服务内部资源进行跳转,超出该服务外就没办法进行跳转了(地址栏不变,但是图片资源又不在这个服务里面),而sendRedirect中则可以任意转(但是地址栏会进行变化,很多图片服务都是内部ip等资源,外网不可以自己访问的,并且地址栏不希望进行改变) 。

  2. 如何保证使用技术B的方式的图片和技术A的图片一样?如何验证呢?

    为了安全,你怎么保证那么多图片由B技术迁移过去都是正常的,如何让自己放心,如何验证呢?

  3. 原来使用的元信息表的地方不能修改,怎么办?

    由于原来使用的元信息表的地方有N个地方,换表(字段一样)的也不可能,修改面太大了。如果不修改如何保证一切正常,并且迁移成功呢?

  4. 收录的地址还必须要打开。

    原来的地址规则还是可以打开,该怎么处理呢?

  5. 不间断,持续提供服务。

    1.把老的历史图片迁移新图片,老的图片还在源源不断的产生,什么时候可以是个头呢?

    2.各各通道不可能一瞬间生效,话外之音就是有新的、有老的共存的时候但是如何又不能影响呢?

    3.先迁移查看图片地址呢? 还是先迁移上传图片地址呢? 2个先后如何确定才可以保证正确呢?

备注:如果是数据迁移,加一个MQ可能就很方便了,但是这里和数据迁移还是有点不同,需要考虑的稍微有点多。

如何做?

针对跳转问题

我们可以把图片资源拿到服务本地,在流写回去(性能不好,并且如果并发各各方面大的话,本次磁盘可能不够,还有一个新的问题存放在本地磁盘的文件什么时候删除呢? 都是问题)???

Nginx代理可以实现跳转并且地址栏不用变化(proxy_pass)。

双写

只有双写才会达到追上,所以必须双写(可能会考虑如果写第一个成功,第二个失败,没关系,后续还有扫描操作补数据),需要建立和原来的元信息表字段一样的表,表面后面多加一个_new即可。修改老服务(在里面添加发送请求到新的,达到双写目的),这样补齐原来老的图片即可。

SQL语句查询数据在A表而不再B表的数据:

select a.id from a left join b on a.id = b.id where b.id is null

通过这样可以不断扫表把数据入到新的图片服务以及新表,把历史数据补齐了。

验证新老图片一样

网上有通过基于像素的比对,但是太耗时,并且需要内存等比较大,一般比较图片大小,长宽以及人抽查看看就行了。

在好友李岩的提醒下,我去试了下md5的确也可以,而且方便很多,感谢!!!

20180815-md5

public static void main(String[] args) throws Exception {
        System.out.println(DigestUtils.md5Hex(new FileInputStream("C:\\Users\\Administrator\\Desktop\\bcd.jpg")));
        System.out.println(DigestUtils.md5Hex(new FileInputStream("C:\\Users\\Administrator\\Desktop\\tab.jpg")));
    }

老的地址还必须打得开

Nginx还是很重要的,通过nginx代理到新的即可,这里需要做一层新老映射,比如olda---->newa这样的地址,有表那么也好梳理的,借助redis里面存储,获取就非常方便了。

切查看再切上传

既然老的地址已经做了代理了,那么先切查看还是先切换上传无所谓了(由于老是查看以及走了新的查看了,所以本质还是需要先切查看)。

各各服务切换新的服务上传接口和查看地址前缀(如果走统一配置就很快,如果走配置文件就一个一个服务走)。

备注:由于表不能修改,或者字段不能修改,调用方太多,那么意味着新服务也是写老表。

刷老表数据

由于新的服务也向老表写数据了,那么必须把一起老表的数据刷成新表里面的新的数据才行(注意就是图片资源路径信息)。

结束语

本人水平有限,难免会有一些理解偏差的地方,如果发现,欢迎各位积极指出,感谢!!!

原文出处:https://www.cnblogs.com/jiangxinlingdu/p/9571003.html

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消