分类 Code 下的文章

总体步骤

类似把大象关进冰箱分为3步:

  1. 把冰箱门打开
  2. 把大象放到冰箱里
  3. 把冰箱门关上

将物理机迁移至ESXi 7.0虚拟机也需要3步:

  1. VMware vCenter Converter Standalone Client将物理机打包成VMware Workstation兼容的vmdk文件;
  2. 将vmdk文件上传至ESXi系统存储,并通过vmkfstools转换其为ESXi7.0兼容的格式;
  3. 用上一步转换而来的虚拟硬盘文件创建虚拟机。

1 打包物理机

  1. WMware官网下载VMware vCenter Converter Standalone Client,可能需要注册一个账号
  2. 在需要打包的物理机上安装并运行VMware vCenter Converter Standalone Client
  3. 点击Convert machine,弹窗中选择source typeThis local machine进入下一步:
    WX20220106-103415-1.png
  4. 在目标系统中按照以下界面选择,建议存储位置这里可以通过插入一个移动硬盘并选择这个盘,以方便后续上传到ESXi:
    WX20220106-103534-2.png
  5. 在选项/Options步骤,编辑Data copy type,只选择需要的打包的分区,比如引导分区、系统盘等
    WX20220106-104151-3.png
  6. 继续点击Next/Finish直到完成转换,稍候片刻,即可获得导出的VMware Workstation兼容的vmdk文件

2 上传vmdk,使用vmkfstools转换格式

由于打包的vmdk是兼容VMware Workstation的版本,是不兼容ESXi的。如果不转换格式的话,会出现类似报错:

无法打开磁盘 scsi0:m: 磁盘类型 n 不受支持或无效。请确保磁盘已导入。

  1. 进入ESXi Web终端,通过存储 -> 数据存储浏览器进入并打开/创建相关文件夹,并上传上一步打包出来的vmdk文件:
    迁移1.png
  2. 找到数据存储所在位置:
    迁移2.png
  3. 主机 -> 管理 -> 服务 中打开SSH服务,详见启用对 ESXi Shell 的访问
  4. 通过终端SSH连接到ESXi服务器
  5. cd到第2步存储所在的文件夹,再进一步cd到上传的vmdk文件所在的文件夹
  6. 执行vmkfstools转换格式命令,记得最后要使用-d thin来使用精简置备模式,以节省空间

    # 进入导入vmdk文件所在的文件夹
    cd /vmfs/volumes/xxxxx248-xxxx75d-07eb-xxxxd6c0/xxxx
    # 转换格式,假定原文件名为orginal.vmdk,转换后的文件名为dest.vmdk
    vmkfstools -i orginal.vmdk dest.vmdk -d thin
  7. 等待片刻,即可享用转换出来的vmdk文件

3 创建虚拟机

创建一个新的虚拟机,添加上一步转换出来的vmdk文件为新的硬盘

  1. 进入ESXi终端,通过虚拟机 -> 新建虚拟机 -> 创建新虚拟机
    迁移3.png
  2. 自定义设置,硬盘选择那里添加一个现有硬盘,选择刚才创建的vmdk文件(dest.vmdk
    迁移4.png
  3. 安装常规步骤创建好虚拟机
  4. 理论上你可以运行你的虚拟机了

参考

LEDE的vmdk在esxi下提示scsi0:0的磁盘类型不受支持或无效_Jian Sun_的博客-程序员宝宝
WorkStation 虚拟机迁移到 ESXi的后续处理. 转载

Nginx settings:

/etc/nginx/sites-available/domain.name.com

include        /etc/nginx/proxy.conf;
limit_req_zone $binary_remote_addr zone=one:10m rate=5r/s;
server_tokens  off;

upstream corshapi {
        server localhost:5001;
}

add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;


limit_req  zone=one burst=10 nodelay;

location /api {
        proxy_pass         http://localhost:5001;
        proxy_http_version 1.1;
        proxy_set_header   Upgrade $http_upgrade;
        proxy_set_header   Connection keep-alive;
        proxy_set_header   Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
}

Reference

  1. Publishing to local IIS failed to include JS files for Pages when using 'abp-script' Tag
  2. Configure IdentityServer4 behind nginx reverse-proxy
  3. Enforce HTTPS in ASP.NET Core
  4. Host ASP.NET Core on Linux with Nginx
  5. Depoloyment Problem: invalid_request
  6. ABP Framework to Azure! - Part 10
  7. Sign-in - IdentityServer 4
  8. Authorization in Angular UI

《架构整洁之道》是Uncle Bob|Bob大叔【美】Robert C. Martin(罗伯特 C. 马丁)在2017年写的介绍软件架构的书。本书从最细节的编程范式,再讲到SOLID设计原则,然后依次介绍高阶的组件、软件架构。后面强调了数据库、框架、Web等是实现细节而非架构。最后则是其他人写的拾遗和半工作经历自传。整本书有点像搭建房子时介绍建筑架构,先从砖和钢筋混凝土到房价再到房子等由小到大介绍开了,很有趣。

作者总结了3中编程范式:

  1. 结构化编程:最传统的,程序是欧几里得公理系统;对函数控制权的直接转移进行了限制和规范;
  2. 面向对象编程:通过封装、继承和多态,对程序控制权的简介转移进行了限制和规范;
  3. 函数式编程:通过变量不可变(函数无状态)、对可变进行隔离,对程序中的赋值进行了限制和规范。

作者总结的架构精髓:SOLID原则,可以有效之道我们如何构建每一个程序模块。

S代表Single Responsibility Principle,即单一责任原则:每个模块都只有一个需要被改变的理由。据说与Conway Law直接相关。

O代表Open Close Principle,即开闭原则:允许新增代码来改变系统的行为,而不允许通过改变老代码来改变系统行为。Software entities (classes, modules, functions) should be open for extension but closed for modification

L代表Liskov Substitution Principle,李氏替换原则:组件之间必须满足设计约束才可以相互替换;派生类(子类)对象可以在程序中代替其基类(超类)对象。

I代表Interface Segregation Principle,接口隔离原则:客户(client)不应被迫使用对其而言无用的方法或功能。Clients should not be forced to depend upon interfaces that they don't use。接口隔离,避免不必要的依赖。

D代表Dependency Inversion Principle,依赖反转原则:高层次的策略性代码不应该依赖于底层的实现性代码,依赖关系应该反过来。例如业务逻辑不应该依赖UI或者数据库。High level modules should not depend upon low level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Details should depend upon abstractions。

作者继续阐明组件构建原则。

组件定义:组件是程序部署的最小单元,即可执行文件和库,比如jar文件。

组件的聚合要满足以下三个原则:

  1. REP 复用/发布等同原则:软件复用的最小粒度应该等同与发布的最小粒度。这样任何变更不会导致过多的发布,或者过度的源代码修改。
  2. CCP 共同闭包原则:把那些会同时修改,并且为相同目的而修改的软件模块(类)放到同一个组件中去,即共同闭包。这实际是SRP在组件级别的重述,因为可维护性的重要性远大于可复用性。我们可以通过组件张力图,去计量共同闭包。
  3. CRP 共同复用原则:不要强迫一个组件的用户依赖他们不需要的东西。

组件的耦合应该满足下面三个原则:

  1. 无循环依赖原则:组件依赖关系中不应该出现环状结构。如果有,可以通过DIP解决。
  2. 稳定依赖原则:依赖关系必须指向更稳定的方向。被依赖的最多的组件应该是最稳定的,因为它难以被修改。计量关系:I = Fan-out/(Fan-in + Fan-out)。接口最稳定。
  3. 稳定抽象原则:一个组件的抽象化程度应该与其稳定性保持一致。

讲完组件,作者开始阐述软件架构。

主要是把策略和细节分离,在整个软件中,合理的划分边界,同时合理的规划好边界之间的依赖关系。同时做好策略与层次的设计:低层次的组件应该去依赖高层次的组件。

业务逻辑作为程序中最核心的用来挣钱/省钱的逻辑,应该位于层次同心圆最中间。而实现细节,或者I/O(UI、数据库等),则应位于最外面。依赖关系则是,最外面依赖最里面。

个人感觉,软件架构计时做好合理的分层,这里包括水平和垂直分层两个部分。水平只的是从UI、业务逻辑、持久化等数据流去分层;垂直分层则是从业务模块和领域的角度去分层,例如订单模块、CRM模块等。一个合理的软件架构,应该同时考虑这两种分层,并选择与之相应较好的侧重点。Salesforce是典型的侧重水平分层的平台,有明确的UI层(Visualforce Page、aura、lwc)、逻辑层(Apex)、数据层(SOQL、DML)。而目前流行的微服务架构,则更侧重垂直分层。

这两种分层的取舍,作者并没有过多解释,只是强调了策略与细节、分层与边界、分层与依赖等更加基础的内容。为什么?我猜是因为在架构上去侧重某种分层,结果就是出现框接,而作者认为框架是细节,并非架构。

作者还强调很多看起来像框架的东西,其实是实现细节

比如数据库、Web、应用程序框架,他们都是实现细节。

作者还对一个视频销售网站的架构设计,进行了精彩的讨论。

在另外一个人写的拾遗部分,主要讨论了作者的理论和自己的理解。

最后,作者回顾了从20世纪60年代到90年代,作者的软件工作生涯。可以从中看到作者不断总结教训经验,慢慢得出本书的这套理论。

参考

  1. douban 架构整洁之道
  2. wiki 开闭原则
  3. wiki 里氏替换原则
  4. wiki 接口隔离原则
  5. wiki SOLID
  6. zhihu 小话设计模式原则之:依赖倒置原则DIP

有时候我们需要在Salesforce页面下载存放为Attachment的文件;或者我们需要把存成Attachment的图片显示在页面上。

内部站点

如果我们文件为Attachment,在Salesforce Internal (即使用Salesforce账户登录的,非Digital Experience, Site.com),则可以使用

 <a href="{!URLFOR($Action.Attachment.Download, attachmentId)}">File Name</a>

下载文件。

或者使用

<img src="{!URLFOR($Action.Attachment.Download, attachmentId)}" />

显示图片。

如果是File,则可以使用Url.getFileFieldURL(entityId, fieldName)

Site.com

Site.com上的则不能用上面的方法,使用的话会直接报错。这时可以通过Salesforce提供的文件下载api /servlet/servlet.FileDownload?file=xxxx~18,不过要注意,一定要使用Salesorce Internal Url,使用Site.com的相关url肯定也会报错。

  1. 首先在后台获取 Salesforce Instance Url 或 Org Domain Url。例如:
    String orgUrl = Url.getOrgDomainUrl().toExternalForm()
  2. 将其传到前台,拼接成下载地址:
    <a href="{!orgUrl + '/servlet/servlet.FileDownload?file=' + attachment.Id}">File Name</a>

参考文档

  1. Visualforce Developer Guide: $Action
  2. Apex Reference Guide: URLClass
  3. stackexchange: How to get salesforce instance url
  4. Salesforce Developer Forum: Download Attachment from Sites??
  5. Salesforce Developer Forum: How to get downloadable link for attachment?

升级后打开前后端均显示503,查询nginx日志显示:

PHP message: Adapter Typecho_Db_Adapter_Mysql is not available

由于之前升级过PHP,因此估计是PHP的问题。修改Typecho的config.inc.php相关代码为:

/** 定义数据库参数 */
$db = new Typecho_Db('Pdo_Mysql', 'typecho_');

恢复正常。