垂直切片架构 - Jimmy Bogard

许多年前,我们开始了一个新的长期项目,首先,我们基于洋葱架构构建了它的架构。在几个月内,这种风格开始显示出裂缝,我们从这种架构转向CQRS。随着转向CQRS,我们开始围绕垂直切片而不是层(无论是平面还是同心,它仍然是层)构建我们的架构。从那以后,在过去7到8年左右的时间里,围绕垂直切片架构构建应用程序和系统的所有方式一直是我们独有的方法,我无法想象回到分层架构方法的限制。 传统的分层/洋葱/清洁架构在其目标是单体的: 这种架构方式问题是实际上只适用于系统中的少数典型请求。此外,我倾向于看到这些架构严重拟合,严格遵守依赖关系管理规则。在实践中,我发现这些规则很少有用,并且你开始得到很多关于真正不应该被抽象的抽象(控制器必须与必须使用存储库的服务进行对话)。 相反,我想对我的系统采用量身定制的方法,我将每个请求视为如何处理其代码的独特用例。因为我的系统整齐地分解为“命令”请求和“查询”请求(HTTP-land中的GET与POST / PUT / DELETE),所以向垂直切片架构的移动使我使用了CQRS。 什么是“垂直切片架构”?在这种风格中,我的架构是围绕不同的具体请求功能而构建的,通过这种方法,我们的每个垂直切片都可以自行决定如何最好地满足请求: (对于获取订单,直接使用ORM转换为DTO,对于订单细节使用原生SQL转换为DTO,对于发票,使用基于聚合根的事件溯源,取消订单使用存储过程,这是一种微服务风格) 在所谓正常的“n层”或六边形或任何架构中,通过垂直切片移除这些层障碍,并沿着变化轴聚合在一起: 在应用程序中添加或更改功能时,通常会在应用程序中涉及到许多不同的“层”。现在改为沿着切片垂直将这些功能聚合在一起。 最小化切片之间的耦合,并最大化切片内的聚合。 通过这种方法,大多数抽象都消失了,我们不需要任何类型的“共享”层抽象,如存储库,服务,控制器。有时我们仍需要这些工具,但我们将交叉切片逻辑共享保持在最低限度。 通过这种方法,我们的每个垂直切片都可以自行决定如何最好地满足请求。 “企业架构模式”一书中的旧域逻辑模式不再需要成为应用程序范围内的选择。相反,我们可以从简单的(事务脚本)开始,并简单地重构从我们在业务逻辑中看到的代码气味中出现的模式。新功能只添加代码,您不会更改共享代码并担心副作用。非常自由! 但是,这种方法有一些缺点,因为它确实假设您的团队了解代码气味和重构。如果您的团队不理解“服务”在将逻辑推送到领域时自己却做得太多相关业务逻辑事情,那么这种模式可能不适合您。(服务类似餐厅服务员,服务员不应该做决定,只是协调者,当然如果你想退菜,服务员会决定说:不能退,菜已经烧了。) 如果您的团队确实理解了重构,并且能够识别何时将复杂的逻辑推入域,进入DDD服务应该是什么,并且熟悉其他Fowler/Kerievsky重构技术,那么您会发现这种架构风格能够远远超过传统的分层/同心架构。 来源:https://www.jdon.com/53095.html

March 24, 2023

关于android手机刷机的各类问题总结

这两周来频繁刷机,更新系统又还原系统,弄懂了很多事情,写一篇日志总结,以便以后查询使用,也希望能够看到的人能避免踩坑,也许第三部分更有价值,可以直接跳过去看。 一、关于刷机 刷机有风险,可能会变砖。不过因为很多手机都留了最后一手:FASTBOOT,所以总能把手机就回来 。 刷机的有不少的方法:卡刷、线刷、OTA。卡刷:一般来说卡刷简单的能够理解为在内存卡中刷机,就是进入Recovery中刷入系统;线刷:线刷事实上能够简单的理解为用USB线刷机;OTA:仅仅要在系统中在线升级就能够成功刷机。 刷机之前需要解锁,一般开放点的厂商都会给相应的解锁工具和权限,只要愿意折腾都可以完成解锁。其实解锁和刷机就是为了获得root权限,这样可以对系统做更大的定制,当然也降低手机的安全性。 刷机要根据自己的手机型号找到相应的刷机包(也就是ROM),要注意是卡刷还是线刷,卡刷就是拷贝到手机卡里刷机,线刷就是用电脑的工具通过手机数据线刷机。 小米的MIUI系统有大量的刷机包,我一直都喜欢用欧版,地址是:https://xiaomi.eu 内网地址是:https://sourceforge.net/projects/xiaomi-eu-multilang-miui-roms/ 二、获得root权限 我用的是小米手机,有两种方法,这里从别的地方搬过来,我只把重要的步骤留下,并且指出可能的坑点。 1、通过替换boot.img方式安装Magisk获取Root权限指南 来源原文:https://miuiver.com/install-magisk-for-xiaomi/ 现在获取手机 Root 主要通过安装 Magisk 实现,这篇文章将以新手视角介绍如何安装使用 Magisk。 准备工作:安装 Magisk 过程中需要用到 fastboot 命令,需要刷写手机 boot 或 Recovery 分区,请确保手机已完成 BL 解锁,不然无法进行 。正常情况下不会丢数据,但是建议都先外置备份手机数据再操作。 下载Magisk 地址 https://github.com/topjohnwu/Magisk/releases (选择下载最新版,然后安装到手机)。 提取相应文件:查看手机上运行的系统版本是多少,下载对应系统版本刷机包,从里面提取相应文件(请见下面说明)。如果之前 Ramdisk 查询结果为“是”,请提取 boot.img 文件如果之前 Ramdisk 查询结果为“否”,请提取 recovery.img 文件。 文件提取方法:如果系统版本有线刷包,可以直接解压提取;如果系统版本只有卡刷包,需要从解压的 payload.bin 文件里提取(老机型卡刷包可以直接提取),将提取到的文件复制到手机上。 生成修补文件:手机打开 Magisk 软件,点击 Magisk 卡片中的“安装”按钮。点击“选择并修补一个文件”,选择之前提取到的 boot.img 或 recovery.img 文件,点击“开始”,然后等待生成修补文件。据 Magisk 文档指出,小米有个别机型 Ramdisk 结果可能不能准确检测。如果修补 recovery.img 文件失败,可以尝试用 boot.img 修补,后面安装也遵循 Ramdisk 结果为“是”的做法。将生成的修补文件复制到电脑上(修补文件默认保存在手机内部存储 Download 目录)。 刷写修补文件:将手机关机,长按音量下键+电源键进入 FASTBOOT 模式,用数据线连接到电脑。电脑打开存放修补文件的文件夹,按住键盘 Shift 键,同时鼠标右键点击文件夹空白处,在右键菜单点击“在此处打开 Powershell 窗口”,然后运行下面刷写命令(命令中的文件名请先自行修改)。如果之前修补 boot.img 文件请用这个命令:.\fastboot flash boot magisk_patched-25200_pU6ZV.img;如果之前修补 recovery.img。文件请用这个命令:.\fastboot flash recovery magisk_patched-25200_pU6ZV.img。刷写完成后用下面命令重启手机:.\fastboot reboot ...

February 15, 2023

解决Xcode 10 、Xcode11、Xcode12升级之后 'string' file not found C++头文件、`libstdc++6.0.9.tbd`库缺失问题

最近公司的移动开发工程师被困在老家,项目有紧急需要修改的地方,我只好亲自上阵,打开Xcode改bug。编译的过程发现小伙子前阵子刚刚升级了,遇到了c++头文件无法编译的问题。网上查了一下,发现这是Xcode的通病,三个版本都有类似的问题。 Xcode10 ‘string’ file not found C++头文件缺失问题 将对应文件拷贝到Xcode10对应目录下 真机: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/c++ 模拟器: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/include/c++ Xcode9 C++头文件github链接:https://github.com/DeCori/Xcode9-cpp.git Xcode10中缺少的libstdc++6.0.9.tbd库 其中文件夹 1、2、3、4 中的文件分别对应复制到Xcode10中的以下4个目录中即可: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/usr/lib/ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/lib/ /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/lib/ /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/lib/ Xcode11和12文件的1路径发生改变: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/usr/lib

April 2, 2022

使用python的opencv库来移除黑色背景图

前两天为了研究隐形数字水印技术,了解了一些OpenCV的用法,涉及到把黑色背景图去掉的方法,别的不多说,直接上代码吧! import os import cv2 path = "D:/build/utensilspictureNew" #文件夹目录 # 遍历文件夹及其子文件夹中的文件,并存储在一个列表中 # 输入文件夹路径、空文件列表[] # 返回 文件列表Filelist,包含文件名(完整路径) def get_filelist(dir): newDir = dir if os.path.isfile(dir): src = cv2.imread(newDir,1) tmp = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY) _, alpha = cv2.threshold(tmp, 0, 255, cv2.THRESH_BINARY) b, g, r = cv2.split(src) rgba = [b, g, r, alpha] dst = cv2.merge(rgba, 4) cv2.imwrite(newDir, dst) print('Done'); elif os.path.isdir(dir): for s in os.listdir(dir): newDir=os.path.join(dir,s) get_filelist(newDir) get_filelist(path) 代码还包括了如何递归遍历文件夹里的文件夹和文件。

October 22, 2021

隐形数字水印技术

这两天需要给项目中的图片加水印,考虑到美观就放弃了显性的水印,而采用隐形的数字水印。利用数字水印的不可见性,在不影响作品的情况下,加入版权信息的数字水印,可抗击拷贝,剪切。 数字水印(DigitalWatermarking)技术是将一些标识信息(即数字水印)直接嵌入数字载体(包括多媒体、文档、软件等)当中,但不影响原载体的使用价值,也不容易被人的知觉系统(如视觉或听觉系统)觉察或注意到,只有通过专用的检测器或阅读器才能提取。数字水印是一个崭新的信息隐藏技术,首次提出这个概念至今也不到20年。 我采用的是github上面的一个开源库blind_watermark (https://github.com/guofei9987/blind_watermark) 这是基于小波变换的数字盲水印,用python来写的,效果还可以,不过通过通信软件截图或者发送之后,就无法获取到数字水印了,这个只能防那些直接拿来使用的盗用者。 另外,如果图片上透明背景的png格式,转换之后会生成黑色底色,这个也很不好,我花了两天时间试图修改源码,还是没有完成。 虽然没有能,但是学会了一些OpenCV的技术。

October 18, 2021

用python给图片添加半透明水印

我一直都是用C#来完成水印的生产,最近捣腾python脚本,查了一下,可以很方便地用python给图片添加半透明水印。 # coding:utf-8 from PIL import Image, ImageDraw, ImageFont def add_text_to_image(image, text): font = ImageFont.truetype('C:\Windows\Fonts\STXINGKA.TTF', 36) # 获取字体 # 添加背景 new_img = Image.new('RGBA', (image.size[0] * 3, image.size[1] * 3), (0, 0, 0, 0)) new_img.paste(image, image.size) # 添加水印 font_len = len(text) rgba_image = new_img.convert('RGBA') text_overlay = Image.new('RGBA', rgba_image.size, (255, 255, 255, 0)) image_draw = ImageDraw.Draw(text_overlay) for i in range(0, rgba_image.size[0], font_len*40+100): for j in range(0, rgba_image.size[1], 200): image_draw.text((i, j), text, font=font, fill=(0, 0, 0, 50)) text_overlay = text_overlay.rotate(-45) image_with_text = Image.alpha_composite(rgba_image, text_overlay) # 裁切图片 image_with_text = image_with_text.crop((image.size[0], image.size[1], image.size[0] * 2, image.size[1] * 2)) return image_with_text if __name__ == '__main__': img = Image.open("test.jpg") im_after = add_text_to_image(img, u'test_output') im_after.save(u'test_output.png')

October 15, 2021

使用Github Action将.NET Core发布到docker Hub

前言 去年公司已经完成所有产品的.NET Core改造工作,团队成员也逐步积累了docker和devops的知识,今年的主要任务之一就是把核心的产品迁移到devops生产线上。本来是打算用微软的Azure平台,因为真的太好用了,我自己的测试站点就一直用Azure来做持续交付工作。但是公司原来的产品、数据、备案都在阿里云上,迁移的话会有大量的工作,包括数据迁移、备案迁移都很麻烦。加上目前国内这种政治绝对正确的要求,搞不准哪天就因为用Azure就撞雷了,虽然很无语,但是也没有办法。 这几天一直在想方案,前年是打算用开源的持续集成(CI)工具Jenkins来配合阿里云,不过去年发现GitHub Action用起来更加顺畅,而我们的代码基本都是托管在GitHub上面,阿里云去年也发布了自己的K8S平台ACK,我们打算当小白鼠,正式使用看看效果如何。 不过在使用ACK之前,我们希望能够把Github上面的代码持续发布到docker Hub上面,去年已经完成了这部分工作,今天整理一下步骤和流程。 一、创建docker Hub账号 首先是到 https://hub.docker.com/ 创建一个账号,并且创建一个自己的repository,可以是公开的,也可以是私有的。另外,设置和GitHub的连接: 二、创建Dockerfile 通过VSCode或者VS创建自动Dockerfile,如果是VS,就右键项目(不是解决方案),添加Docker支持,VS会自动生成这个项目的Dockerfile文件,不用做任何修改。 三、提交整个解决方案 我们的项目一般都是位于一个解决方案里面,所以一个解决方案可能保护多个项目,这个没有问题,把整个解决方案都提交到GitHub上面,当然必须是本地可以编译通过并且可以运行的代码。网上很多教程都没有说清楚这种项目的打包细节,我后面会重点说一下,因为对于一个初学者,很容易在这里迷茫。 四、设置GitHub的密钥 需要把第一步创建的Hub账号填写到GitHub的settings里面: 五、编写Action的WorkFlow 通过Github的Action,可以创建很多类型的工作流WorkFlow,非常方便。 可以看到,几乎涵盖了所有国内外常用云平台的模板。 当然了,也包含了几乎所有常用开发语言的模板,太牛了。 Github上还有非常多通用的Action,你可以直接引用来使用,这里我不多说,贴一个我们可以运行的WorkFlow: name: .NET on: push: branches: [ master ] pull_request: branches: [ master ] jobs: docker: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Setup .NET Core uses: actions/setup-dotnet@v1 with: dotnet-version: 3.1.x - name: Push to Docker Hub uses: docker/build-push-action@v1 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} dockerfile: ./Academy.PCCore/Dockerfile repository: academy/academypc tags: v0.0.1 tag_with_ref: true 这里重点说一下后面的这几个变量: 1、username和password就是第四步里面设置的变量。 2、dockerfile的路径问题,路径“./”就是指当前在Github的这个respository的根目录,比如: 这里我只需要将Academy.PCCore项目打成docker,Dockerfile也在这个文件夹的根目录。 3、repository,这个就是在Docker Hub里面创建的仓储Respository的路径,两边一定要一直,否则无法提交。 ...

March 15, 2021

插画版Kubernetes指南[此文非原创]

插画版Kubernetes指南(小孩子也能看懂的kubernetes教程) 是根据一个视频翻译过来的,比较形象 编者按:Matt Butcher 是 Deis 的平台架构师,热爱哲学,咖啡和精雕细琢的代码。有一天女儿走进书房问他什么是 Kubernetes,于是就有了这本插画版的 Kubernetes 指南,讲述了勇敢的 Phippy(一个 PHP 应用),在 Kubernetes 的冒险故事,满满的父爱有木有! 某一天 有一天,女儿走进书房问我:『亲爱的爸爸,什么是 Kubernetes 呢?』 我回答她:『Kubernetes 是一个开源的 Docker 容器编排系统,它可以调度计算集群的节点,动态管理上面的作业,保证它们按用户期望的状态运行。通过使用「labels」和「pods」的概念,Kubernetes 将应用按逻辑单元进行分组,方便管理和服务发现。』 女儿更疑惑了……于是就有了这个故事。 给孩子的插画版 Kubernetes 指南 很久很久以前,有一个叫 Phippy 的 PHP 应用,她很单纯,只有一个页面。她住在一个托管服务里,周围还有很多可怕的应用,她都不认识,也不想去认识,但是他们却要共享这里的环境。所以,她一直都希能有一个属于自己的环境:一个可以称作 home 的 webserver。 每个应用的运行都要依赖一个环境,对于一个 PHP 应用来说,这个环境包括了一个 webserver,一个可读的文件系统和 PHP 的 engine。 有一天,一只可爱的鲸鱼拜访了 Phippy,他建议 Phippy 住在容器里。Phippy 听从了鲸鱼的建议搬家了,虽然这个容器看起来很好,但是……怎么说呢,就像是漂浮在海上的一个小房间一样,还是没有家的感觉。 不过容器倒是为应用提供了隔离的环境,在这个环境里应用就能运行起来。但是这些相互隔离的容器需要管理,也需要跟外面的世界沟通。共享的文件系统,网络,调度,负载均衡和资源分配都是挑战。 『抱歉……孩子……』鲸鱼耸耸肩,一摇尾消失在了海平面下…… Phippy 还没有来得及失望,就看到远方驶来一艘巨轮,掌舵的老船长非常威风。这艘船乍一看就是大了点,等到船走近了,Phippy 才发现船体两边挂满了皮筏。 老船长用充满智慧的语气对 Phippy 说:『你好,我是 Kube 船长』。 『Kubernetes』是希腊语中的船长,后来的『Cybernetic』和『Gubernatorial』这两个词就是从 Kubernetes 衍生来的。Kubernetes 项目由 Google 发起,旨在为生产环境中成千上万的容器,构建一个健壮的平台。 ...

June 2, 2020

.NET Core微服务: ASP.NET Core on Docker

ASP.NET Core on Docker 指的是将 ASP.NET Core 应用运行在 Docker 容器中,通过容器化技术实现应用的开发、部署和运行。 Docker 为 ASP.NET Core 提供了统一的运行环境,使应用能够在开发、测试和生产环境中保持一致,避免因操作系统或依赖差异导致的问题。 在微服务架构中,每个服务通常都会被打包成一个独立的 Docker 镜像,并以容器形式运行。这样做具有以下优势: 环境一致性:开发、测试、生产使用相同的运行环境,减少“本地能跑、线上不能跑”的问题。 部署简单:应用及其依赖全部封装在镜像中,部署过程标准化。 资源隔离:每个微服务运行在独立容器中,互不影响。 快速扩缩容:可以根据业务压力快速启动或销毁容器实例。 易于持续交付:方便与 CI/CD 流水线结合,实现自动构建、测试和部署。 一个典型的 ASP.NET Core Docker 化流程包括: 编写 ASP.NET Core 应用。 编写 Dockerfile,定义镜像构建方式。 使用 Docker 构建应用镜像。 运行 Docker 容器。 在生产环境中结合 Docker Compose 或 Kubernetes 等容器编排平台管理多个微服务。 总体而言,ASP.NET Core on Docker 是 .NET 微服务体系的重要基础,它利用 Docker 的容器化能力,使应用具备更好的可移植性、部署效率和运维能力,为微服务架构的落地提供了可靠支撑。

June 1, 2020

选择Angular而不是Vue

最近团队要选择前端开发框架,我进行了大量对比,最终选择了Angular,我承认Vue也很优秀,React也超级棒,但Angular非常适合我们。我们需要的就是这样一个真正的框架,包含了组件化方案、模块化方案、测试方案、表单验证、路由、国际化方案和安全方案。 Angular 的工程师将我们需要的所有功能做了不错的整合。如果使用 Vue,我可能还要面临更多选择。Angular 的一份文档涵盖了开发中的方方面面。如果使用 Vue,可能每个功能要去看不同的文档。Angular 更强势更主观,它的文档对于如何完成某个功能给出了明确的建议。我们团队的成员有不同的编程背景,虽然有三个全职的前端,但是还有十几个 Java 和 Python 程序员,他们也可能会参与前端工作,Angular 的文档能让这些成员快速适应环境。 Angular = Vue + vue-router + axios + karma + 表单验证插件 + i18n … 我们需要typescript来告别原来脓肿不堪的js代码 使用TypeScript,告别对臃肿代码的重构,让自己的编程真正能够面向对象吧。 一千个人有一千种React代码风格,但是Angular的代码风格只有一种。你会发现Angular的每一处都是最佳实践,设计模式的运用是基于Google多年的Java编程经验的,响应式的应用也是基于微软对于操作系统中异步处理的经验总结。 无数的编程概念都有其历史厚重感,而Angular将他们汇聚到了一起。windows中的linq‘时间上的数组’,spring中的依赖注入,处理HDFS的MR,到linux线程本地存储,再到前端界的MVVM,MVC。 Angular优势: Angular 的工程师将我们需要的所有功能做了不错的整合。如果使用 Vue,我可能还要面临更多选择。 Angular 的一份文档涵盖了开发中的方方面面。如果使用 Vue,可能每个功能要去看不同的文档。 Angular 更强势更主观,它的文档对于如何完成某个功能给出了明确的建议。我们团队的成员有不同的编程背景,虽然有三个全职的前端,但是还有十几个 Java 和 Python 程序员,他们也可能会参与前端工作,Angular 的文档能让这些成员快速适应环境。 核心原因:Angular 是一个完整的框架。

June 10, 2019