2026年1月

之前的订阅,也被强制取消了。
刚刚找了半天,好不容找到个注册入口,结果跳转到微软官网了。
有没有知情的?

我有一个 spa 的项目,都是国内用户,需要用到模糊搜索标题,数据库用的 LeanCloud 的 class ,结果 LeanCloud 将于 2027 年 1 月 12 日停止对外提供服务。
最近在找迁移方案,改开始选的是 AWS DynamoDB ,结果这货不支持不能模糊查找,模糊查询只能靠 Scan 配合 Filter ,这在百万级数据下会产生高昂的费用且延迟巨大。
改 AWS S3 + EFS + Lambda + API Gateway 方案,项目改造好了,迁移到 AWS 中国,尼玛中国这个 API Gateway 垃圾死调不通,API Gateway 的测试工具能访问到 Lambda ,各种排查,折腾了两天,搜了一下才知道这货要申请白名单,放弃了。

准备转 azure 阵营,结果我之前到订阅被取消了,也不给新注册了。。。。。。
又是充实的一个周末。。。。

点赞 + 关注 + 收藏 = 学会了

整理了一个NAS小专栏,有兴趣的工友可以关注一下 👉 《NAS邪修》

买 NAS 不玩 Docker 乐趣少一半。

但 Docker 的镜像(简单理解为软件安装包吧)是放在国外服务器保存的,我们要下载这些镜像全凭运气。

绿联 NAS 虽然推荐了一个加速器(https://docker.1ms.run),但有些镜像还是搜到下载不到。

比如 memos 这款高颜值的笔记工具,我下载了几次都失败了。

先别急删掉 Docker,我们多配置几个镜像加速器就可以了。

绿联 NAS 的 Docker 镜像加速器配置方法很简单。

打开 Docker,切换到「镜像」页面,点击右上角的“齿轮”按钮。

在「镜像仓库」这里,点击下图箭头所指的「加速器配置」按钮。

把这堆地址都填进去,点击「确定」按钮就行了~

回到「镜像」面板,搜索你想安装的镜像就能下载了。


以上就是本文的全部内容啦,想了解更多NAS玩法可以关注《NAS邪修》👏

最后推荐一下玩 NAS 的工友,在 NAS 上装一个 n8n 接入大模型,可以帮你定时定候完成各种工作,比如签到啦、写文章啦、生成海报和视频啦、自动发布到各大平台啦~

想了解 n8n 的工友可以关注我的专栏👉 《n8n修炼手册》

点赞 + 关注 + 收藏 = 学会了

点赞 + 关注 + 收藏 = 学会了

整理了一个NAS小专栏,有兴趣的工友可以关注一下 👉 《NAS邪修》

Memos 是一款开源免费、隐私优先的轻量化笔记工具,支持 Docker 一键部署到 NAS(数据本地存储,完全自主掌控)。它支持纯文本和 Markdown 格式,可通过标签、日历分类笔记,还能实现笔记引用、插入图片 / 附件等实用功能,低资源占用不拖慢设备,记想法、列待办、存资料都合适。

本文使用群晖 NAS 部署 memos,其他 NAS 或者在电脑用 Docker 部署的方法大同小异。

首先在“File Station”的“docker”文件夹里创建一个“memos”文件夹。

然后打开”Container Manager“创建一个新项目,相关配置如下图所示。

输入以下代码(注意代码格式!!!)

services:
  memos:
    image: neosmemo/memos:latest
    container_name: memos
    volumes:
      - .:/var/opt/memos
    ports:
      - 5230:5230

开启“通过 Web Station 设置网页门户”

接下来打开“web Station”新建一个“网络门户”。

相关配置如下图所示。

端口设置一个不跟其他项目冲突的数字即可,我用的是 2345

完成上面的操作后,打开浏览器,输入 NAS的IP + 端口(本例用的是2345),就可以使用 memos了。

首次使用需要创建一个账号。

在登录页下方可以设置 memos 系统使用什么语言以及主题色。

登录后就可以开始写笔记了。它支持 Markdown 语法,挺适合用来写博客的。


以上就是本文的全部内容啦,想了解更多NAS玩法可以关注《NAS邪修》👏

最后推荐一下玩 NAS 的工友,在 NAS 上装一个 n8n 接入大模型,可以帮你定时定候完成各种工作,比如签到啦、写文章啦、生成海报和视频啦、自动发布到各大平台啦~

想了解 n8n 的工友可以关注我的专栏👉 《n8n修炼手册》

点赞 + 关注 + 收藏 = 学会了

​基于最新鸿蒙系统的技术书籍《鸿蒙HarmonyOS 6应用开发:从零基础到App上线》上市啦,要知道 HarmonyOS 6 在一个多月前的10月22日才正式发布,因此这本鸿蒙教程可谓贴近最新的 HarmonyOS 6 系统。

当前 HarmonyOS 6 的装机量迅猛增长,有望在春节前突破5000万台大关,可见鸿蒙系统的应用开发将越来越流行,甚至借助国产化的浪潮,未来在国内移动操作系统领域一举夺魁也不是不可能。

有鉴于此,博主精心编撰了 HarmonyOS 6 的应用开发教程《鸿蒙HarmonyOS 6应用开发:从零基础到App上线》,从基础到高级,从理论到实战,从 UI 到 AI ,仅需一本书籍,即可让读者掌握鸿蒙应用的常见开发技能。

鸿蒙应用开发与安卓应用开发同为App开发,比如鸿蒙版微信和安卓版微信都是即时通信App,二者在实现技术上并无多少本质区别。所以《鸿蒙HarmonyOS 6应用开发:从零基础到App上线》一书以《Android Studio开发实战:从零基础到App上线(第3版)》为蓝本,把安卓系统的App教程改造为鸿蒙系统的App教程,以便安卓开发者能够按图索骥迅速上手。欣喜的是,《Android Studio开发实战:从零基础到App上线(第3版)》提到的安卓开发技术,绝大部分都能在鸿蒙系统找到对应的平替技术,而且还是更简单的代码实现。

作为《Android Studio开发实战:从零基础到App上线(第3版)》一书的鸿蒙姊妹篇,《鸿蒙HarmonyOS 6应用开发:从零基础到App上线》仍然采取了由浅入深、循序渐进的章节体例,其中前8章是基础部分,主要讲解 DevEco Studio 的环境搭建、ArkTS语言编程基础、鸿蒙App开发的各种常用组件、鸿蒙App开发的页面转场和消息交互、鸿蒙App的几种数据存储方式等;后8章是进阶部分,主要讲解鸿蒙App开发的后台任务、手势交互、动画特效、网络通信、多媒体、感知定位、人工智能、多端部署等。

曾经有老读者咨询“从零基础到App上线”系列书籍的第4版何时面世,现在博主终于可以说,“从零基础到App上线”的第4版已经出版啦,而且第4版是鸿蒙版本的“从零基础到App上线”,它就叫做《鸿蒙HarmonyOS 6应用开发:从零基础到App上线》,该书把安卓版教程平替为鸿蒙版教程,也是一个勇敢的尝试。

《鸿蒙HarmonyOS 6应用开发:从零基础到App上线》在讲解知识点的同时给出了大量实战范例,方便读者迅速将所学的知识运用到实际开发中。通过本书的学习,读者能够掌握3类主流App的基本开发技术,包括购物App(电子商务)、聊天App(即时通信)、娱乐App(短视频分享)。另外,能够学会开发一些趣味应用,包括计算器、录音笔、电子相册、打牌游戏、指南针、水平仪、卫星浑天仪、登山助手、附近交友、速记助手、人脸识别等等。可见《Android Studio开发实战:从零基础到App上线(第3版)》一书提到的实战项目,本书基本提供了对应的鸿蒙版App。

《鸿蒙HarmonyOS 6应用开发:从零基础到App上线》的随书源码包括客户端部分和服务端部分,其中客户端的App代码基于 DevEco Studio 6.0.0 Release 开发,并使用 API 20 的 SDK (HarmonyOS 6.0.0)编译与调试通过,测试机型包括 Mate 60 Pro 和 nova 12 Pro 。配套的服务端源码采用 Java WEB 框架,结合 MySQL 数据库,并基于 IDEA 开发。

写在前面,本人目前处于求职中,如有合适内推岗位,请加:lpshiyue 感谢。同时还望大家一键三连,赚点奶粉钱。本系列已完结,完整版阅读课联系本人

高可用不是简单的冗余堆砌,而是无状态化、水平扩展与故障转移三者协同的艺术品

在掌握了系统压测方法论,能够准确评估系统容量边界后,我们面临一个更根本的挑战:如何让系统在真实流量冲击和故障发生时保持稳定?高可用架构设计正是解决这一挑战的核心手段。本文将深入解析无状态化、水平扩展与故障转移三大支柱技术的协同设计,帮助构建真正弹性可靠的系统架构。

1 高可用的本质:从故障避免到故障容忍的哲学转变

1.1 高可用性的核心价值重估

传统观念中,高可用意味着尽可能避免故障,而在分布式系统环境下,这一理念已转变为快速发现和恢复故障。根据Gartner的统计,企业IT系统平均每分钟的宕机成本超过5600美元,对于大型电商平台,这个数字可能达到数万美元。

高可用设计的哲学转变体现在三个层面:

  • 从完美预防到快速恢复:接受故障必然性,专注于最小化MTTR(平均修复时间)
  • 从单体坚固到分布式韧性:通过系统设计而非组件质量保证可用性
  • 从人工干预到自动化愈合:建立系统自愈能力,减少人工依赖

这种转变使我们需要重新定义高可用的成功标准:不是追求100%无故障,而是确保故障发生时业务影响可控、恢复过程自动

1.2 可用性等级的理性定位

不同业务场景对可用性有不同要求,理性定位是避免过度设计的第一步:

99.9%可用性(年停机时间≤8.76小时)适合内部管理系统
99.95%可用性(年停机时间≤4.38小时)适合一般业务系统
99.99%可用性(年停机时间≤52.6分钟)适合核心业务系统
99.999%可用性(年停机时间≤5.26分钟)适合金融交易系统

确立合理的可用性目标后,我们才能有针对性地选择技术方案,在成本与可靠性间找到平衡点。

2 无状态化:弹性架构的基石

2.1 无状态设计的本质与价值

无状态化不是简单去除会话数据,而是将状态与计算分离,使应用实例变得可替代。这种分离是水平扩展和故障转移的基础。

有状态架构的典型问题

// 问题示例:会话绑定导致扩展困难
@RestController
public class StatefulController {
    // 会话状态存储在内存中
    private Map<String, UserSession> userSessions = new ConcurrentHashMap<>();
    
    @GetMapping("/userinfo")
    public String getUserInfo(HttpSession session) {
        UserSession userSession = (UserSession) session.getAttribute("currentUser");
        // 此实例绑定特定用户会话,无法随意替换
        return userSession.getUserInfo();
    }
}

状态内嵌导致实例不可替换

无状态化改造方案

@Configuration
@EnableRedisHttpSession // 启用Redis会话存储
public class StatelessConfig {
    // 会话外部化配置
}

@RestController
public class StatelessUserController {
    @GetMapping("/userinfo")
    public String getUserInfo(@RequestHeader("Authorization") String token) {
        // 从Redis获取用户信息,不依赖本地状态
        String userJson = redisTemplate.opsForValue().get("session:" + token);
        User user = JsonUtil.fromJson(userJson, User.class);
        return user.toString();
    }
}

状态外置使实例可任意替换

2.2 无状态化的多层次实践

无状态化需要在不同层级实施协同策略:

应用层无状态:会话数据外部化到专用存储(Redis Cluster)
服务层无状态:API设计保证请求自包含,不依赖服务实例内存状态
任务层无状态:计算任务参数和结果完全自包含,支持任意重调度

无状态设计的业务适配策略

  • 完全无状态:适合查询类、计算型业务(商品查询、价格计算)
  • 外部状态:适合需要会话保持但无需实例绑定的业务(用户登录状态)
  • 轻量状态:适合短暂业务流程,状态生命周期与请求周期一致

2.3 无状态架构的代价与应对

无状态化不是银弹,需要认识其代价并制定应对策略:

性能代价:状态外部化增加网络开销,需要通过缓存、批处理优化
一致性挑战:分布式状态需要处理并发更新,采用乐观锁或版本控制
复杂度增加:需要引入额外组件(Redis、ZooKeeper),增加运维复杂度

合理的无状态化是有选择的无状态,而非盲目去除所有状态。核心是确保实例可替换性,而非完全消除状态。

3 水平扩展:流量压力的分布式化解

3.1 水平扩展的本质与架构前提

水平扩展通过增加实例数量而非提升单机性能来应对流量增长,其有效性直接依赖于无状态化程度。

水平扩展的架构前提

  • 无状态设计:实例间无数据依赖,可任意增减
  • 负载均衡:流量按策略分发到多个实例
  • 服务发现:动态感知实例上下线,实时更新路由
  • 健康检查:自动隔离故障实例,保证流量只会到达健康节点

3.2 分层扩展策略

系统不同层级需要采用不同的水平扩展策略:

接入层扩展:通过DNS轮询、全局负载均衡实现流量入口扩展

# Nginx上游服务配置示例
upstream backend_servers {
    server 10.0.1.10:8080 max_fails=3 fail_timeout=30s;
    server 10.0.1.11:8080 max_fails=3 fail_timeout=30s;
    server 10.0.1.12:8080 backup;  # 备份节点
    least_conn;  # 最少连接负载均衡
}

接入层通过集群化实现扩展

应用层扩展:无状态服务实例水平扩展,结合自动伸缩策略

# Kubernetes HPA配置示例
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: frontend-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: frontend
  minReplicas: 3
  maxReplicas: 100
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70

应用层根据负载自动伸缩

数据层扩展:通过分片、读写分离等技术实现数据访问扩展

-- 数据库分片示例:用户数据按ID分片
-- 分片1:用户ID以0-4结尾
CREATE TABLE users_1 (
    id BIGINT PRIMARY KEY,
    name VARCHAR(100),
    -- 其他字段
);

-- 分片2:用户ID以5-9结尾  
CREATE TABLE users_2 (
    id BIGINT PRIMARY KEY,
    name VARCHAR(100),
    -- 其他字段
);

数据层通过分片实现水平扩展

3.3 水平扩展的粒度控制

科学的水平扩展需要精细化粒度控制,避免过度或不足扩展:

单元化扩展:按业务单元而非整体系统进行扩展,如用户服务独立于订单服务扩展
弹性伸缩:基于预测和实时指标动态调整实例数量,平衡性能与成本
分级扩展:核心服务与非核心服务差异化扩展策略,确保关键业务资源

4 故障转移:从被动应对到主动容错

4.1 故障检测:快速发现的艺术

有效的故障转移始于精准的故障检测,需要在及时性与准确性间找到平衡:

多层次健康检查策略

# Kubernetes就绪与存活探针配置
apiVersion: v1
kind: Pod
metadata:
  name: web-application
spec:
  containers:
  - name: web
    image: nginx:latest
    livenessProbe:
      httpGet:
        path: /health
        port: 8080
      initialDelaySeconds: 30
      periodSeconds: 10
      timeoutSeconds: 5
      failureThreshold: 3
    readinessProbe:
      httpGet:
        path: /ready  
        port: 8080
      initialDelaySeconds: 5
      periodSeconds: 5
      timeoutSeconds: 3
      failureThreshold: 1

通过探针机制实现精准故障检测

智能故障判定:结合多个指标(响应时间、错误率、资源使用率)综合判断,避免单指标误判。

4.2 故障隔离:防止雪崩的屏障

故障转移不仅是将流量从故障实例移走,更重要的是隔离故障影响

熔断器模式:在连续失败达到阈值时自动熔断,避免重试风暴

@Component
public class ProductService {
    @CircuitBreaker(name = "productService", 
                   fallbackMethod = "getProductFallback")
    public Product getProduct(Long productId) {
        return remoteProductService.getProduct(productId);
    }
    
    public Product getProductFallback(Long productId, Exception ex) {
        return cacheService.getBasicProduct(productId);
    }
}

熔断器防止故障扩散

隔离策略

  • 线程池隔离:不同服务使用独立线程池,避免资源竞争
  • 信号量隔离:控制并发调用数,防止资源耗尽
  • 超时控制:设置合理超时时间,避免长时间阻塞
  • 限流降级:流量超过阈值时自动降级,保护系统不被冲垮

4.3 流量切换:无缝转移的技术实现

故障转移的核心是流量重路由,需要在不同层级实现协同:

负载均衡器切换:健康检查失败时自动从路由表中移除故障节点

upstream backend {
    server 10.0.1.10:8080 max_fails=3 fail_timeout=30s;
    server 10.0.1.11:8080 max_fails=3 fail_timeout=30s;
    server 10.0.1.12:8080 backup;
    
    # 故障转移配置
    proxy_next_upstream error timeout http_500 http_502 http_503;
}

负载均衡器实现自动故障转移

服务网格流量管理:基于Istio等服务网格实现细粒度流量控制

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: product-service
spec:
  host: product-service
  trafficPolicy:
    outlierDetection:
      consecutiveErrors: 5
      interval: 10s
      baseEjectionTime: 30s
      maxEjectionPercent: 50

服务网格提供高级故障检测与转移能力

5 三大支柱的协同设计

5.1 协同工作的架构模式

无状态化、水平扩展与故障转移不是孤立技术,而是相互依赖的有机整体:

无状态化赋能水平扩展:只有无状态设计,才能实现真正的无缝水平扩展
水平扩展增强故障转移:多实例为故障转移提供目标节点,使转移成为可能
故障转移保障水平扩展:在扩展过程中,故障转移确保个别实例故障不影响整体

协同架构示例

用户请求 → 负载均衡器(故障检测/转移)
                   ↓
           无状态应用集群(水平扩展)
                   ↓  
          集中式状态存储(Redis集群)
                   ↓
          数据存储层(分片/主从)

5.2 协同设计的反模式与陷阱

伪无状态陷阱:表面无状态但实际存在隐性状态依赖(如本地缓存、文件存储)
不平衡扩展:计算层扩展但数据层成为瓶颈,或相反
过度转移:过于敏感的故障检测导致频繁转移,反而影响稳定性
单点转移:故障转移机制本身存在单点故障

5.3 协同效能的度量体系

三大支柱的协同效果需要可度量的指标验证:

无状态化程度指标

  • 实例启动时间(应小于30秒)
  • 请求路由一致性(任意实例处理结果相同)
  • 状态外部化比例(超过90%状态外部化)

水平扩展效能指标

  • 线性扩展比(实例增加与性能提升比例)
  • 扩展速度(从触发到完成扩展的时间)
  • 资源利用率(避免过度或不足扩展)

故障转移质量指标

  • 故障检测时间(秒级检测)
  • 转移恢复时间(分钟级恢复)
  • 转移成功率(超过99%的转移成功)

6 实战案例:电商平台高可用架构演进

6.1 单体架构的高可用改造

初始状态:单体应用,会话绑定,数据库单点

改造步骤

  1. 无状态化改造:用户会话外置到Redis集群
  2. 水平扩展准备:应用容器化,配置负载均衡
  3. 故障转移基础:数据库主从分离,读写分离
  4. 渐进式迁移:先读流量,后写流量;先非核心功能,后核心功能

改造效果:可用性从99.9%提升至99.95%,扩展时间从小时级降至分钟级

6.2 微服务架构的高可用深化

架构特点:服务拆分,分布式依赖,复杂调用链

深化措施

  • 精细化无状态:API网关无状态化,业务服务按需无状态
  • 弹性扩展策略:基于业务优先级差异化扩展策略
  • 智能故障转移:基于调用链分析的精准故障定位和隔离

深化效果:可用性提升至99.99%,故障恢复时间从30分钟降至5分钟以内

总结

高可用架构的本质是通过无状态化、水平扩展、故障转移三大支柱的协同设计,构建能够容忍故障、快速恢复的弹性系统。

核心洞察

  1. 无状态化是基础:只有解耦状态与计算,才能实现真正的弹性
  2. 水平扩展是手段:通过分布式架构将集中式风险分解为可管理单元
  3. 故障转移是保障:在故障发生时快速隔离和恢复,最小化业务影响
  4. 协同设计是关键:三大支柱必须统一设计,相互配合,而非孤立优化

成功的高可用架构不是追求零故障,而是确保在故障发生时:

  • 系统能够快速检测定位问题
  • 故障影响被有效隔离,防止扩散
  • 业务流量被无缝转移到健康实例
  • 系统能够自动恢复,减少人工干预

在云原生时代,随着Kubernetes、服务网格等技术的成熟,高可用能力已经日益平台化、标准化。然而,技术选型只是起点,真正的挑战在于根据业务特点合理运用这些能力,构建既可靠又经济的高可用体系。


📚 下篇预告
《CDN与边缘缓存策略——静态、动态与签名鉴权的组合拳》—— 我们将深入探讨:

  • 🌐 缓存层次体系:浏览器缓存、边缘缓存、中心缓存的协同分工
  • 动态内容加速:边缘计算、智能路由与协议优化技术
  • 🔐 安全缓存挑战:签名URL、权限验证与敏感内容保护
  • 📊 缓存效能优化:命中率提升、失效策略与成本平衡
  • 🚀 边缘架构演进:从内容分发到边缘计算的范式转变

点击关注,构建高效安全的全球内容分发体系!

今日行动建议

  1. 评估现有应用的无状态化程度,制定状态外部化改造路线
  2. 设计水平扩展的容量规划与自动伸缩策略
  3. 建立多层级的故障检测与转移机制,定期进行故障演练
  4. 制定三大支柱协同效能的度量体系,持续优化高可用能力

如果说 2025 还是 AI 编程的探索期,程序员可以一边喝着咖啡,一边看 AI 如何实现。

到了 2026 马年,一定是快马加鞭的一年,从探索转变为生产力的提升,只不过鞭子不是抽向 AI,而是抽向程序员。

成本

2025 年公司大力投入 AI 编程,GitHub Copilot,Cursor,Claude Code 都可以用。每月 200 美元的额度也很大方,甚至不够用还可以提额。

这个成本如果由个人承担,的确是笔不小的开销。但对公司来说,这笔账太划算了。

假设一个程序员的月薪是 1.4 万,只要使用 AI 能提效 10%,这笔投入也是值得的。更何况大部分程序员月薪会更高,只提效 5%,都是赚的。

再换一个角度,新招一个月薪 2.8 万的人还是让 20 个员工用上 AI 编程,一定是后者回报更大。

产出

公司多了投入,自然会要求产出,尤其是已经过了探索阶段。

原来评审时,可以说有技术难点需要调研,也可以说自己手上有别的事,做不过来,毕竟人力就是原来的限制,再无聊的代码也需要人一行一行打上去。

但有了 AI 之后,这些限制都不是问题了,至少在领导那里是这样想的。有难题,就让 AI 来解决。做不过来,就多开几个 AI ,人会累,AI 又不会。

如果你想反驳说 AI 也不是那么好用,领导可能会让你回去反思一下,为什么你觉得不好用。

而且也更容易内卷了,比如团队中有一个人 AI 用的很好,如果跟他有工作上的配合,那进度也得与他保持一致。再一次印证了,AI 并不会淘汰人,而是会用 AI 的人淘汰掉不会用 AI 的人

AI 并没有减轻程序员的工作量,反而换了一种方式,成了进一步压榨程序员的工具。

压榨

程序员的编码工作可以简单地拆成编和码两部分。编就是构思如何实现,这是脑力劳动。码就是敲击键盘打码,这是体力劳动。工作原本是脑力与体力交替进行的,脑子累了可以手敲会代码,手累了可以想想方案。

但有了 AI,程序员的工作被彻底改变了。AI 可以做大部分规划工作以及全部实现工作,而程序员只需要确保 AI 没有跑偏。

程序员变成了一个分时处理的 CPU,哪个 AI 窗口需要确认了,就切过去看一下。看完你的看你的,一刻也不停歇。

表面上是程序员在使用 AI,实际上是通过 AI 在压榨程序员最后一点价值。

工作变成了纯纯的脑力劳动,再也不会有那种不用动脑,敲着无聊代码的轻松时间了。

考核

公司每天会统计每个人的 AI 用量,也会有总的排名,但如何考核程序员的工作产出始终是一个难题。

再傻的领导也不会让大家卷 AI 用量,毕竟程序员有无数的办法烧掉更多的 token。结果就是,产出提没提高不知道,成本一定是在往上涨的。

在没有找到一个很好的考核标准前,我们要尽快适应新的工作方式。

应对

作为程序员,在适应了 AI 编程之后,下一步就是改变原有的工作方式。

之前的工作大多是单线进行的,设计、开发、测试、上线。而有了 AI,可以多线并行。你不再是一个单打独斗的程序员,而是一个带领着 AI 员工的 team leader,这个团队的大小完全取决于你拆解、分配、处理任务的能力。

不要再把注意力只放在如何写好代码上,而是要关注如何管理好这个团队。

这不仅仅是为了适应工作的压力,更是一次职业形态的进化。蜜月期也许结束了,但对于那些善于驾驭 AI 的人来说,真正属于超级个体的黄金时代,才刚刚开始。

📦 AppPorts

https://github.com/wzh4869/AppPorts
外置硬盘拯救世界!/ External drives save the world!

一款专为 macOS 设计的应用程序迁移与链接工具。
轻松将庞大的应用程序迁移至外部存储,同时保持系统无感运行。

✨ 简介

Mac 的内置存储空间寸土寸金。AppPorts 允许您一键将 /Applications 目录下的应用程序迁移到外部移动硬盘、SD 卡或 NAS ,并在原位置保留应用入口,让系统误以为应用仍在本地。

对 macOS 系统而言,应用依然“存在”于本地,您可以像往常一样启动它们,但实际占用的却是廉价的外部存储空间。

🚀 核心功能

  • 📦 应用瘦身:一键将几十 GB 的大型应用(如 Logic Pro, Xcode, 游戏等)迁移至外置硬盘。
  • 🔗 Contents 链接:采用 Contents 目录链接 方案,专为适配 macOS 机制设计。
    • 原理:在本地保留 .app 文件夹结构,仅将内部的 Contents 数据目录链接至外部存储。
    • 空间占用:本地仅保留文件夹索引信息,占用空间受文件系统块大小限制(通常可忽略不计)。
    • 兼容性:Finder 不会显示快捷方式小箭头,且支持 macOS 26 的 "App 菜单" 显示。
  • 🛡️ 安全机制
    • 自动识别并锁定 系统应用,防止误操作破坏系统。
    • 迁移前检测 运行状态,防止损坏正在运行的应用。
  • ↩️ 随时还原:只需点击“还原”,即可将应用完整迁回本地磁盘,符号链接自动移除。
  • 🎨 现代 UI
    • 原生 SwiftUI 开发,丝滑流畅。
    • 完美适配 深色模式
    • 支持 中英双语,可随系统或手动切换。
  • ♿️ 无障碍优化
    • VoiceOver 深度适配:支持列表行整体朗读、转子快捷操作。
    • 语义化界面:屏蔽装饰性图标干扰,状态标签支持清晰的语音播报。
    • 盲文支持:新增 Braille 语言选项,界面文字可直接显示为点字。
  • 🌍 全球化支持
    • 20+ 种语言支持
    • 本地化单位:文件大小会自动遵循当前语言的数字和单位格式习惯。
  • 🔍 快速检索:内置搜索栏,快速定位本地或外部应用。

🏆 为什么选择 AppPorts ?

相较于市面上其他方案,AppPorts 采用了独特的 Contents 链接 技术,兼顾了美观、兼容性与系统整洁度。

方案 AppPorts 传统软链
Finder 图标 原生 (无箭头) ❌ 有箭头 (快捷方式)
Launchpad 完美索引 ⚠️ 经常失效
App 菜单 (macOS 26) 完美支持 ❌ 不支持
文件系统整洁度 极佳 (仅 1 个链接) ✅ 极佳 (仅 1 个链接)
维护与还原 毫秒级 ✅ 毫秒级

📸 截图

欢迎页 主界面
Welcome Main
深色模式 语言切换
Dark Lang

🛠️ 安装与运行

系统要求

  • macOS 14.0 (Sonoma) 或更高版本。

下载安装

请前往 Releases 页面下载最新版本的 AppPorts.dmg

⚠️ “AppPorts”已损坏,无法打开

如果打开应用时遇到此提示(且系统建议移到废纸篓),这是因为应用没有进行开发者签名,被 macOS 的 Gatekeeper 机制拦截。
(注意:以下命令假设您已将 AppPorts 拖入 应用程序 文件夹)
您需要在终端运行以下命令来移除隔离属性,即可正常打开:

xattr -rd com.apple.quarantine /Applications/AppPorts.app

⚠️ 权限说明

首次运行时,AppPorts 需要 “完全磁盘访问权限” 才能读写 /Applications 目录。

  1. 打开 系统设置 -> 隐私与安全性
  2. 选择 完全磁盘访问权限
  3. 点击 + 号,添加 AppPorts 并开启开关。
  4. 重启 AppPorts 。

目前表情的像素我是控制在 350px,在一些 RSS 开启 webview 上浏览时就没啥好体验,尝试通过行内样式减小图片显示宽度好像也没生效。

图片宽高像素降低 -> 图片体积减小 -> 图片变糊force_smile

SVG 显示效果最好,不过 SVG 导出即便做了优化,尺寸还是较大,个别 emoji 超过 1M,就算 cdn 首次加载也会消耗一些流量。

每天在 VS Code 里敲代码的你,真的把这个编辑器的潜力发挥到极致了吗?同样的工作,为什么别人的开发速度总是比你快?答案可能就在这些插件里。今天,我整理了 16 款亲测好用的 VS Code 插件,涵盖代码编辑、版本控制、智能提示等多个维度,帮你从"普通开发者"进化为"高效战士"!

📋 目录

为什么需要安装插件?

VS Code 本身已经非常强大,但它的真正魅力在于插件生态系统。通过安装合适的插件,你可以:

能力提升说明
编码速度智能提示、代码片段自动补全
🎨 代码质量自动格式化、语法检查、拼写检查
🔍 代码导航快速跳转、书签标记、Git 历史追踪
👁️ 实时预览前端页面、SVG 图片即时查看
🌈 视觉体验彩色缩进、精美图标让编辑更愉悦

一、代码编辑与格式化类

1. 🎨 EditorConfig for VS Code

作用:统一不同编辑器和操作系统的代码风格(缩进、换行符等)。
使用场景
团队协作时,有人用 Windows 有人用 Mac,有人喜欢 Tab 缩进有人喜欢空格,导致代码风格混乱。EditorConfig 让所有人遵循同一套规则。
核心配置
在项目根目录创建 .editorconfig 文件:

root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
💡 安装后自动生效,无需额外配置。

2. ✨ Prettier - Code formatter

作用:一键美化代码,统一格式(单双引号、分号、缩进等)。
使用场景
写完代码后,格式乱糟糟?一键 Shift + Alt + F(Windows)或 Shift + Option + F(Mac),瞬间变整齐。
核心优势

  • 支持 JavaScript、TypeScript、CSS、SCSS、JSON 等多种语言
  • 可保存时自动格式化
  • 团队风格统一,消灭"格式圣战"
    配置示例.prettierrc):

    {
    "printWidth": 100,
    "tabWidth": 2,
    "singleQuote": true,
    "semi": true,
    "trailingComma": "es5"
    }

    3. 🔍 ESLint

    作用:JavaScript/TypeScript 代码质量检查,发现潜在错误。
    使用场景

  • 忘记声明变量
  • 使用了未定义的函数
  • React Hooks 使用违规
  • 不建议的语法写法
    功能亮点
  • 实时在代码中显示错误和警告
  • 提供自动修复建议
  • 支持 React、Vue、TypeScript 等框架

    ⚠️ 建议配合 Prettier 使用:ESLint 管质量,Prettier 管颜值。

    4. 🎭 Stylelint

    作用:CSS/SCSS/Less 样式代码检查与自动修复。
    使用场景

  • CSS 冗余代码(重复定义)
  • 颜色格式不统一
  • 选择器写法不规范
  • SCSS 语法错误
    配置示例.stylelintrc.json):

    {
    "extends": ["stylelint-config-standard"],
    "rules": {
      "selector-class-pattern": null
    }
    }

    5. 🌈 indent-rainbow

    作用:让缩进层级显示为彩色,像彩虹一样。
    使用场景

  • 长嵌套代码快速识别层级
  • 避免缩进错误(多空格或少空格)
  • 代码阅读更愉悦
    效果预览

    function example() {
    if (true) {        // 红色缩进
      const arr = [   // 绿色缩进
        1,             // 蓝色缩进
        2,
        3
      ];
    }
    }
    🎯 小技巧:适合初学者识别代码块边界,老手可选择性安装。

    二、代码片段与智能提示类

    6. ⚡ ES7+ React/Redux/React-Native snippets

    作用:提供 React 常用代码片段的快速输入。
    使用场景
    再也不用每次手写 useEffectuseCallbackReact.memo 的完整模板,输入简写自动展开。
    常用触发词

    触发词展开内容
    rafceReact 函数组件 + 默认导出
    rafcReact 箭头函数组件
    uefuseEffect Hook
    ustuseState Hook
    ucbuseCallback Hook
    remReact.memo 包装

    示例

    // 输入 rafce + Tab,自动展开:
    import React from 'react'
    const MyComponent = () => {
    return (
      <div>rafce</div>
    )
    }
    export default MyComponent

    7. 🎯 Tailwind CSS IntelliSense

    作用:Tailwind CSS 类名智能提示、悬停预览、自动补全。
    使用场景

  • 不记得某个工具类名怎么写
  • 想知道某个类名的具体样式
  • 防止拼写错误(如 bg-red500 写成 bg-red-500
    核心功能
  • ✅ 实时类名补全
  • ✅ Hover 显示具体样式值
  • ✅ Lint 提示未知类名
  • ✅ 支持自定义配置文件读取

    💡 Tailwind 开发者的必备神器,效率提升 50%+!

    8. 💚 Vue (Official)

    作用:Vue 官方插件,提供语法高亮、智能提示、代码片段。
    使用场景

  • Vue 2/3 项目开发必备
  • .vue 文件语法高亮
  • Vue 指令自动补全
  • Props、Emits 类型提示
    支持特性
  • ✅ 单文件组件(SFC)完整支持
  • ✅ TypeScript 支持
  • ✅ Pinia 状态库集成
  • ✅ Vite 模块智能解析

    三、Git 版本控制类

    9. 🔬 GitLens — Git supercharged

    作用:VS Code 中最强大的 Git 增强插件。
    核心功能

    功能说明
    📝 代码作者鼠标悬停显示这行代码是谁写的
    🕐 提交时间显示代码最后修改时间
    🔀 分支对比当前分支与其他分支的差异
    📋 提交详情点击查看完整的 commit 信息和文件变更
    🔍 Blame 功能显示每一行代码的提交记录

    使用技巧

  • Ctrl + Shift + G 打开 Git 面板
  • 点击代码行左侧的 Git 图标查看作者
  • 使用 "GitLens: Toggle File Blame" 查看整个文件的 blame

    🏆 被称为 Git 必装插件,强烈推荐!

    10. 📊 Git Graph

    作用:以可视化图形展示 Git 提交历史和分支关系。
    使用场景

  • 直观查看分支合并情况
  • 快速切换分支
  • 查看 tag 标签
  • 找到某个 commit 的父节点
    功能亮点
  • 🌳 树状图展示提交历史
  • 🏷️ 显示标签(Tags)
  • 🔀 显示远程分支
  • ⬇️ 支持 fetch/pull/push 操作

    💡 按 Ctrl + Shift + G 打开 Git 面板,点击 "Git Graph" 查看图形。

    11. 📜 Git History

    作用:查看文件或目录的 Git 历史记录。
    核心功能

  • 查看某个文件的所有提交历史
  • 比较两个版本的差异
  • 恢复文件到某个历史版本
  • 搜索特定提交
    使用方式
  • 右键点击文件
  • 选择 "Git: View File History"
  • 点击某个 commit 查看详细变更
  • 点击 "Open File" 可查看历史版本

    四、开发工具与预览类

    12. 🌐 Live Server

    作用:启动本地开发服务器,支持热更新。
    使用场景

  • HTML/CSS/JavaScript 原型开发
  • 静态页面实时预览
  • 修改代码后浏览器自动刷新
    核心优势
  • ✅ 一键启动服务器
  • ✅ 支持实时热更新
  • ✅ 支持跨域请求
  • ✅ 可自定义端口号
    使用方式
  • 右键点击 index.html
  • 选择 "Open with Live Server"
  • 浏览器自动打开 http://127.0.0.1:5500/

    前端开发必备,告别手动刷新!

    13. 🚀 open in browser

    作用:一键在浏览器中打开当前 HTML 文件。
    使用场景

  • 快速预览静态页面
  • 支持 Chrome、Firefox、Edge 等多浏览器
  • 无需启动服务器
    快捷键

    操作Windows/LinuxMac
    在默认浏览器打开Ctrl + BCmd + B

    14. 🖼️ Svg Preview

    作用:实时预览 SVG 图片,支持代码与视图同步。
    使用场景

  • SVG 图标调试
  • 查看路径、坐标、颜色
  • 实时修改代码预览效果
    核心功能
  • ✅ 分屏显示:左侧代码,右侧预览
  • ✅ 支持拖拽 SVG 文件直接预览
  • ✅ 显示 SVG 的尺寸、路径信息
  • ✅ 支持动画预览

    五、辅助工具类

    15. 🔖 Bookmarks

    作用:在代码中设置书签,快速跳转到重要位置。
    使用场景

  • 跨多个文件快速定位
  • 记住某个函数的位置
  • 大文件中标记关键段落
    快捷键

    操作快捷键
    切换书签Ctrl + Alt + K
    跳转到上一个书签Ctrl + Alt + J
    跳转到下一个书签Ctrl + Alt + L
    清除所有书签Ctrl + Shift + K

    效果展示

    // 🔖 书签标记在函数名前
    function importantFunction() {
    // 这是一个重要函数,需要频繁查看
    console.log('Hello');
    }
    // 🔖 另一个书签
    function anotherFunction() {
    // ...
    }
    💡 适合调试大项目时记录关键位置!

    16. ✅ Code Spell Checker

    作用:检查代码中的拼写错误,避免因单词写错导致的 Bug。
    使用场景

  • 变量名拼写错误(consoel.logconsole.log
  • 注释中的英文拼写错误
  • 防止复制粘贴引入的错别字
    核心功能
  • ✅ 实时拼写检查
  • ✅ 支持驼峰命名识别
  • ✅ 可添加自定义字典
  • ✅ 支持多种语言
    配置示例(添加自定义词汇):

    "cSpell.words": [
    "react",
    "tailwindcss",
    "github"
    ]
    🎯 特别适合非英语母语开发者,减少低级拼写错误!

    17. 🎨 Icon Theme: Material

    作用:为文件和文件夹提供精美的 Material Design 风格图标。
    视觉提升

    文件类型图标样式
    React⚛️ React 图标
    Vue💚 Vue 绿色图标
    TypeScript🔷 TS 蓝色方块
    CSS/Sass🎨 彩色样式图标
    文件夹📁 不同颜色区分

    优势

  • ✅ 一眼识别文件类型
  • ✅ 文件夹颜色区分(src、dist、node_modules)
  • ✅ 提升视觉愉悦度
  • ✅ 支持自定义图标主题

    🌈 强烈推荐安装,让编辑器颜值提升一个档次!

    安装方式

    方法一:通过扩展商店安装(推荐)

  • 打开 VS Code
  • Ctrl + Shift + X(Mac:Cmd + Shift + X)打开扩展面板
  • 在搜索框中输入插件名称
  • 点击 "Install" 安装

    方法二:命令面板安装

  • Ctrl + Shift + P(Mac:Cmd + Shift + P
  • 输入 Extensions: Install Extensions
  • 搜索并安装

    方法三:通过 setting.json 自动格式化配置

    在项目根目录中先创建.vscode目录,然后在.vscode目录中创建一个setting.json文件,配置自动格式化规则。

    {
    "editor.fontSize": 12,
    "editor.tabSize": 2,
    "eslint.enable": true,
    "editor.formatOnSave": true,
    "editor.formatOnType": true,
    "eslint.validate": [
      "vue",
      "html",
      "javascript",
      "typescript",
      "javascriptreact",
      "typescriptreact"
    ],
    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "prettier.requireConfig": true,
    "prettier.semi": false,
    "editor.codeActionsOnSave": {
      "source.fixAll": "explicit",
      "source.fixAll.eslint": "explicit",
      "source.fixAll.stylelint": "explicit"
    },
    "javascript.format.insertSpaceBeforeFunctionParenthesis": false,
    "search.exclude": {
      "**/node_modules": true,
      "**/bower_components": true,
      "**/target": true,
      "**/logs": true
    },
    "css.validate": false,
    "less.validate": false,
    "scss.validate": false,
    "stylelint.validate": [
      "css",
      "less",
      "postcss",
      "scss",
      "sass",
      "stylus",
      "vue"
    ],
    "git.autofetch": true,
    "cSpell.userWords": [
      "antd",
      "axios",
      "childs",
      "commitlint",
      "daterange",
      "echarts",
      "graphlib",
      "loadfj",
      "moveend",
      "tailwindcss",
      "vuepress",
      "vuex",
    ],
    "workbench.startupEditor": "none",
    "diffEditor.ignoreTrimWhitespace": false,
    "workbench.iconTheme": "material-icon-theme"
    }

    方法四:通过 extensions.json 批量安装

    在.vscode目录中创建一个 extensions.json 文件,记录团队推荐插件,新成员可一键同步。

    {
    "recommendations": [
      // 代码编辑与格式化
      "esbenp.prettier-vscode",          // Prettier - Code formatter
      "dbaeumer.vscode-eslint",          // ESLint
      "stylelint.vscode-stylelint",      // Stylelint
      "EditorConfig.EditorConfig",       // EditorConfig for VS Code
      "oderwat.indent-rainbow",          // indent-rainbow
    
      // 代码片段与智能提示
      "dsznajder.es7-react-js-snippets", // ES7+ React/Redux/React-Native snippets
      "bradlc.vscode-tailwindcss",       // Tailwind CSS IntelliSense
      "Vue.volar",                       // Vue (Official)
    
      // Git 版本控制
      "eamodio.gitlens",                 // GitLens — Git supercharged
      "mhutchie.git-graph",              // Git Graph
      "donjayamanne.githistory",         // Git History
    
      // 开发工具与预览
      "ritwickdey.liveserver",           // Live Server
      "techer.open-in-browser",          // open in browser
      "SimonSiefke.svg-preview",         // Svg Preview
    
      // 辅助工具
      "alefragnani.bookmarks",           // Bookmarks
      "streetsidesoftware.code-spell-checker", // Code Spell Checker
      "PKief.material-icon-theme"        // Icon Theme: Material
    ]
    }
    

生效方式

团队协作:将 .vscode/extensions.json 和 .vscode/extensions.json 提交到 Git 仓库。
拉取代码:当团队成员 git pull 代码并在 VS Code 打开该项目时,右下角会弹出提示。
一键安装:点击弹窗中的“安装全部”按钮,VS Code 就会自动帮你装好所有插件。

总结

今天介绍的 16 款插件涵盖了前端开发的各个环节:

类别插件数量核心价值
代码编辑与格式化5统一代码风格,提升可读性
代码片段与智能提示3加速编码,减少重复劳动
Git 版本控制3可视化管理,追溯代码历史
开发工具与预览3实时反馈,提升开发体验
辅助工具2减少错误,提升导航效率

安装建议

  • 🌟 必装(5款):ESLint、Prettier、GitLens、Live Server、ES7+ React Snippets
  • 🌟 推荐(6款):EditorConfig、Tailwind CSS IntelliSense、Git Graph、Bookmarks、Code Spell Checker、Icon Theme: Material
  • 💡 可选(5款):Stylelint、indent-rainbow、Vue (Official)、open in browser、Svg Preview(根据技术栈选择)

    💡 小贴士:不要一次安装过多插件,根据项目需求逐步添加,避免 VS Code 变得卡顿。

    希望这篇教程对你有所帮助!如有问题,欢迎交流讨论。

本文由mdnice多平台发布

实现 Docker Hub 到 Azure ACR 的自动化镜像同步

本文介绍了如何使用 GitHub Actions 和 image-syncer 工具,实现 Docker Hub 镜像到 Azure Container Registry 的自动化同步,解决了国内及部分 Azure 区域访问 Docker Hub 速度慢的问题,提升了镜像的可用性和 Azure 环境的部署效率。

<!-- truncate -->

背景/引言

HagiCode 项目使用 Docker 镜像作为核心运行时组件,主要镜像托管在 Docker Hub。随着项目发展和 Azure 环境部署需求的增加,我们遇到了以下痛点:

  • 镜像拉取速度慢,Docker Hub 在国内及部分 Azure 区域访问受限
  • 依赖单一镜像源存在单点故障风险
  • Azure 环境下使用 Azure Container Registry 能获得更好的网络性能和集成体验

为解决这些问题,我们需要建立一个自动化的镜像同步机制,将 Docker Hub 的镜像定期同步到 Azure ACR,确保用户能够在 Azure 环境中获得更快的镜像拉取速度和更高的可用性。

关于 HagiCode

我们正在开发 HagiCode——一款 AI 驱动的代码智能助手,让开发体验变得更智能、更便捷、更有趣。

智能——AI 全程辅助,从想法到代码,让编码效率提升数倍。便捷——多线程并发操作,充分利用资源,开发流程顺畅无阻。有趣——游戏化机制和成就系统,让编码不再枯燥,充满成就感。

项目正在快速迭代中,如果你对技术写作、知识管理或者 AI 辅助开发感兴趣,欢迎来 GitHub 看看。

技术方案对比

在制定解决方案时,我们对比了多种技术方案:

1. image-syncer(最终选择)

  • 增量同步:仅同步变更的镜像层,显著减少网络传输
  • 断点续传:网络中断后可恢复同步
  • 并发控制:支持配置并发线程数,提升大镜像同步效率
  • 完善的错误处理:内置失败重试机制(默认 3 次)
  • 轻量级部署:单二进制文件,无依赖
  • 多仓库支持:兼容 Docker Hub、Azure ACR、Harbor 等

2. Docker CLI

  • 不支持增量同步:每次都需要拉取完整的镜像内容
  • 效率较低:网络传输量大,时间长
  • 简单易用:使用熟悉的 docker pull/push 命令

3. Azure CLI

  • 复杂度高:需要配置 Azure CLI 认证
  • 功能限制:az acr import 功能相对单一
  • 原生集成:与 Azure 服务集成良好

架构设计决策

决策 1:同步频率设置为每日 UTC 00:00

  • 平衡镜像新鲜度和资源消耗
  • 避开业务高峰期,减少对其他操作的影响
  • Docker Hub 镜像通常在每日构建后更新

决策 2:同步所有镜像标签

  • 保持与 Docker Hub 的完全一致性
  • 为用户提供灵活的版本选择
  • 简化同步逻辑,避免复杂的标签过滤规则

决策 3:使用 GitHub Secrets 存储认证信息

  • GitHub Actions 原生支持,安全性高
  • 配置简单,易于管理和维护
  • 支持仓库级别的访问控制

风险评估与缓解

风险 1:Azure ACR 认证信息泄露

  • 使用 GitHub Secrets 加密存储
  • 定期轮换 ACR 密码
  • 限制 ACR 用户权限为仅推送
  • 监控 ACR 访问日志

风险 2:同步失败导致镜像不一致

  • image-syncer 内置增量同步机制
  • 自动失败重试(默认 3 次)
  • 详细的错误日志和失败通知
  • 断点续传功能

风险 3:资源消耗过大

  • 增量同步减少网络传输
  • 可配置并发线程数(当前设置为 10)
  • 监控同步的镜像数量和大小
  • 在非高峰时段运行同步

核心解决方案

我们采用 GitHub Actions + image-syncer 的自动化方案,实现从 Docker Hub 到 Azure ACR 的镜像同步。

实施步骤

1. 准备阶段

  • 在 Azure Portal 中创建或确认 Azure Container Registry
  • 创建 ACR 访问密钥(用户名和密码)
  • 确认 Docker Hub 镜像仓库访问权限

2. 配置 GitHub Secrets

在 GitHub 仓库设置中添加以下 Secrets:

  • AZURE_ACR_USERNAME: Azure ACR 用户名
  • AZURE_ACR_PASSWORD: Azure ACR 密码

3. 创建 GitHub Actions 工作流

在 .github/workflows/sync-docker-acr.yml 中配置工作流:

  • 定时触发:每天 UTC 00:00
  • 手动触发:支持 workflow_dispatch
  • 额外触发:publish 分支推送时触发(用于快速同步)

4. 工作流执行流程

sequenceDiagram
    participant GH as GitHub Actions
    participant IS as image-syncer
    participant DH as Docker Hub
    participant ACR as Azure ACR

    Note over GH: 触发工作流
    GH->>IS: 下载并执行 image-syncer
    IS->>DH: 获取镜像 manifest 和标签列表
    DH-->>IS: 返回镜像元数据
    IS->>ACR: 获取已存在的镜像信息
    ACR-->>IS: 返回目标镜像信息
    IS->>IS: 对比差异,识别变更的镜像层
    Note over IS: 增量同步:仅传输变更的镜像层
    IS->>DH: 拉取变更的镜像层
    DH-->>IS: 返回镜像层内容
    IS->>ACR: 推送变更的镜像层到 ACR
    ACR-->>IS: 返回推送结果
    IS-->>GH: 返回同步统计信息
    GH->>GH: 记录同步日志并上传 artifact

GitHub Actions 工作流实现

以下是实际运行的工作流配置(.github/workflows/sync-docker-acr.yml):

name: Sync Docker Image to Azure ACR

on:
  schedule:
    - cron: "0 0 * * *" # 每天 UTC 00:00
  workflow_dispatch: # 手动触发
  push:
    branches: [publish]

permissions:
  contents: read

jobs:
  sync:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Download image-syncer
        run: |
          # 下载 image-syncer 二进制文件
          wget https://github.com/AliyunContainerService/image-syncer/releases/download/v1.5.5/image-syncer-v1.5.5-linux-amd64.tar.gz
          tar -zxvf image-syncer-v1.5.5-linux-amd64.tar.gz
          chmod +x image-syncer

      - name: Create auth config
        run: |
          # 生成认证配置文件 (YAML 格式)
          cat > auth.yaml <<EOF
          hagicode.azurecr.io:
            username: "${{ secrets.AZURE_ACR_USERNAME }}"
            password: "${{ secrets.AZURE_ACR_PASSWORD }}"
          EOF

      - name: Create images config
        run: |
          # 生成镜像同步配置文件 (YAML 格式)
          cat > images.yaml <<EOF
          docker.io/newbe36524/hagicode: hagicode.azurecr.io/hagicode
          EOF

      - name: Run image-syncer
        run: |
          # 执行同步 (使用新版 --auth 和 --images 参数)
          ./image-syncer --auth=./auth.yaml --images=./images.yaml --proc=10 --retries=3

      - name: Upload logs
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: sync-logs
          path: image-syncer-*.log
          retention-days: 7

配置说明

1. 触发条件

  • 定时触发:cron: "0 0 *" - 每天 UTC 00:00 执行
  • 手动触发:workflow_dispatch - 允许用户在 GitHub UI 手动运行
  • 推送触发:push: branches: [publish] - 发布分支推送时触发(用于快速同步)

2. 认证配置 (auth.yaml)

hagicode.azurecr.io:
  username: "${{ secrets.AZURE_ACR_USERNAME }}"
  password: "${{ secrets.AZURE_ACR_PASSWORD }}"

3. 镜像同步配置

docker.io/newbe36524/hagicode: hagicode.azurecr.io/hagicode

此配置表示将 docker.io/newbe36524/hagicode 的所有标签同步到 hagicode.azurecr.io/hagicode

4. image-syncer 参数

  • --auth=./auth.yaml: 认证配置文件路径
  • --images=./images.yaml: 镜像同步配置文件路径
  • --proc=10: 并发线程数为 10
  • --retries=3: 失败重试 3 次

GitHub Secrets 配置清单

在 GitHub 仓库的 Settings → Secrets and variables → Actions 中配置:

Secret 名称描述示例值获取方式
AZURE_ACR_USERNAMEAzure ACR 用户名hagicodeAzure Portal → ACR → Access keys
AZURE_ACR_PASSWORDAzure ACR 密码xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxAzure Portal → ACR → Access keys → Password

使用说明

1. 手动触发同步

  1. 访问 GitHub 仓库的 Actions 标签页
  2. 选择 Sync Docker Image to Azure ACR 工作流
  3. 点击 Run workflow 按钮
  4. 选择分支并点击 Run workflow 确认

2. 查看同步日志

  1. 在 Actions 页面点击具体的工作流运行记录
  2. 查看各个步骤的执行日志
  3. 在页面底部的 Artifacts 区域下载 sync-logs 文件

3. 验证同步结果

# 登录到 Azure ACR
az acr login --name hagicode

# 列出镜像及其标签
az acr repository show-tags --name hagicode --repository hagicode --output table

注意事项和最佳实践

1. 安全建议

  • 定期轮换 Azure ACR 密码(建议每 90 天)
  • 使用专用的 ACR 服务账户,限制权限为仅推送
  • 监控 ACR 的访问日志,及时发现异常访问
  • 不要在日志中输出认证信息
  • 不要将认证信息提交到代码仓库

2. 性能优化

  • 调整 --proc 参数:根据网络带宽调整并发数(建议 5-20)
  • 监控同步时间:如果同步时间过长,考虑减少并发数
  • 定期清理日志:设置合理的 retention-days(当前为 7 天)

3. 故障排查

问题 1:认证失败
Error: failed to authenticate to hagicode.azurecr.io

解决方案:

  1. 检查 GitHub Secrets 是否正确配置
  2. 验证 Azure ACR 密码是否过期
  3. 确认 ACR 服务账户权限是否正确
问题 2:网络超时
Error: timeout waiting for response

解决方案:

  1. 检查网络连接
  2. 减少并发线程数(--proc 参数)
  3. 等待网络恢复后重新触发工作流
问题 3:镜像同步不完整
Warning: some tags failed to sync

解决方案:

  1. 检查同步日志,识别失败的标签
  2. 手动触发工作流重新同步
  3. 验证 Docker Hub 源镜像是否正常

4. 监控和告警

  • 定期检查 Actions 页面,确认工作流运行状态
  • 设置 GitHub 通知,及时获取工作流失败通知
  • 监控 Azure ACR 的存储使用情况
  • 定期验证镜像标签一致性

常见问题和解决方案

Q1: 如何同步特定标签而不是所有标签?

修改 images.yaml 配置文件:

# 仅同步 latest 和 v1.0 标签
docker.io/newbe36524/hagicode:latest: hagicode.azurecr.io/hagicode:latest
docker.io/newbe36524/hagicode:v1.0: hagicode.azurecr.io/hagicode:v1.0

Q2: 如何同步多个镜像仓库?

在 images.yaml 中添加多行配置:

docker.io/newbe36524/hagicode: hagicode.azurecr.io/hagicode
docker.io/newbe36524/another-image: hagicode.azurecr.io/another-image

Q3: 同步失败后如何重试?

  • 自动重试:image-syncer 内置重试机制(默认 3 次)
  • 手动重试:在 GitHub Actions 页面点击 Re-run all jobs

Q4: 如何查看同步的详细进度?

  • 在 Actions 页面查看实时日志
  • 下载 sync-logs artifact 查看完整日志文件
  • 日志文件包含每个标签的同步状态和传输速度

Q5: 同步需要多长时间?

  • 首次全量同步:根据镜像大小,通常需要 10-30 分钟
  • 增量同步:如果镜像变更小,通常 2-5 分钟
  • 时间取决于网络带宽、镜像大小和并发设置

扩展功能建议

1. 添加同步通知

在工作流中添加通知步骤:

- name: Notify on success
  if: success()
  run: |
    echo "Docker images synced successfully to Azure ACR"

2. 实现镜像标签过滤

在工作流中添加标签过滤逻辑:

- name: Filter tags
  run: |
    # 仅同步以 v 开头的标签
    echo "docker.io/newbe36524/hagicode:v* : hagicode.azurecr.io/hagicode:v*" > images.yaml

3. 添加同步统计报告

- name: Generate report
  if: always()
  run: |
    echo "## Sync Report" >> $GITHUB_STEP_SUMMARY
    echo "- Total tags: $(grep -c 'synced' image-syncer-*.log)" >> $GITHUB_STEP_SUMMARY
    echo "- Sync time: ${{ steps.sync.outputs.duration }}" >> $GITHUB_STEP_SUMMARY

总结

通过本文介绍的方法,我们成功实现了从 Docker Hub 到 Azure ACR 的自动化镜像同步。这个方案利用 GitHub Actions 的定时触发和手动触发功能,结合 image-syncer 的增量同步和错误处理机制,确保了镜像的及时同步和一致性。

我们还讨论了安全最佳实践、性能优化、故障排查等方面的内容,帮助用户更好地管理和维护这个同步机制。希望本文能够为需要在 Azure 环境中部署 Docker 镜像的开发者提供有价值的参考。

参考资料


互动引导

感谢您的阅读,如果您觉得本文有用,快点击下方点赞按钮👍,让更多的人看到本文。

AI 辅助声明

本内容采用人工智能辅助协作,经本人审核,符合本人观点与立场。

元信息

行情 API 的正确使用方式

常见问题

在行情系统开发中,常见以下问题:

  • 首页行情列表每秒轮询 K 线接口获取最新价
  • 所有页面都建立 WebSocket 连接以实现"实时更新"
  • 系统启动时直接订阅 WebSocket,但未获取可用品种列表
  • 页面切换时旧的 WebSocket 连接未关闭

这些问题的根源在于缺乏正确的使用心智模型。
即不清楚在什么阶段该使用什么接口。

大多数 API 文档会说明接口返回的数据结构。
但不会说明接口的适用场景和使用时机。


行情 API 的本质:数据分层

行情 API 不是接口的集合,而是一套数据分层系统。

构建行情系统时,系统在不同阶段对数据的需求完全不同:

1. 数据使用阶段

  • 启动阶段:系统需要获取可交易品种列表
  • 展示阶段:页面需要显示当前价格
  • 实时阶段:需要在价格变化时主动推送

2. 数据类型

  • 快照:当前时刻的价格、涨跌幅(适合列表、首页)
  • 历史:过去一段时间的价格走势(适合图表、回测)
  • 持续流:价格变化时主动推送(适合实时盯盘、交易执行)

3. 系统复杂度

  • REST API:简单、稳定、易维护,需要主动轮询
  • WebSocket:实时、高效,但需要处理连接管理、重连、心跳

理解这三个维度,可以明确每个接口的适用场景。


行情 API 的分层设计

1. 可用交易品种(Symbols)

系统启动的第一步是获取可用品种列表。

硬编码品种代码会导致以下问题:

  • 退市品种无法及时移除
  • 新上市品种无法及时添加

建议在系统启动时调用品种列表接口,并缓存结果。

多市场统一命名的价值

统一的命名规则可以用同一套代码逻辑处理不同市场的数据:

  • 港股:700.HK9988.HK
  • 美股:AAPL.USTSLA.US
  • 外汇:EURUSDGBPUSD

这避免了为每个市场编写适配层。

接口示例

GET /v1/symbols/available?market=HK&limit=10

使用建议

  • 系统启动时调用一次,缓存结果
  • 不要在每次查询行情前调用此接口
  • 定期更新建议频率为每天一次

多市场统一 symbol 示意图


2. Ticker(实时快照)

Ticker 接口适用于大部分"显示当前价格"的场景。
行情列表页、首页概览、定时刷新的看板。

使用 K 线接口获取最新价存在以下问题:

  • K 线接口返回的数据结构更复杂
  • 需要处理时间对齐问题
  • 无法一次查询多个品种

Ticker 接口的优势:

  • 返回数据轻量
  • 一次请求可查询多个品种(通常支持 50 个左右)
  • 不需要处理时间对齐问题

接口示例

GET /v1/market/ticker?symbols=700.HK,AAPL.US

返回数据

{
  "code": 0,
  "message": "success",
  "data": [
    {
      "symbol": "700.HK",
      "last_price": "602.5",
      "volume_24h": "16003431",
      "high_24h": "606",
      "low_24h": "598",
      "timestamp": 1768982936000
    }
  ]
}

使用建议

只要不是需要实时价格跳动的场景。
Ticker + 定时刷新(5-10 秒)即可满足需求。

Ticker 适用场景示意图

3. K 线(结构化历史)

K 线接口的核心参数是 interval(时间间隔)。
决定了数据的颗粒度。

不同的分析场景对数据颗粒度的要求不同:

  • 1m:1 分钟 K 线,适合短线交易、实时图表
  • 1h:1 小时 K 线,适合日内分析
  • 1d:日 K 线,适合中长期分析、回测

接口示例

GET /v1/market/kline?symbol=AAPL.US&interval=1d&limit=30

使用建议

  • 图表展示:使用 limit 参数(如"显示最近 30 天")
  • 历史回测:使用时间范围参数(如"2023 年 1 月到 3 月的数据")

K线 vs 实时数据对比图

4. WebSocket(实时流)

WebSocket 的代价包括:

  • 维护长连接(心跳、重连、异常处理)
  • 处理订阅管理
  • 处理消息队列
  • 处理网络波动

适用场景

  • 实时盯盘(延迟要求在秒级以内)
  • 价格预警(价格触发阈值时需要立即通知)
  • 高频数据监控(需要毫秒级数据更新)

不适用场景

  • 行情列表页
  • 历史图表
  • 低频监控

以上场景使用 REST API + 定时刷新即可。

接口示例

const ws = new WebSocket('wss://api.example.com/v1/realtime?api_key=YOUR_API_KEY');

ws.onopen = () => {
  ws.send(JSON.stringify({
    cmd: 'subscribe',
    data: { channel: 'ticker', symbols: ['700.HK'] }
  }));
};

设计限制

外汇品种通常仅支持 ticker 频道(不支持 depth 和 trade)。
因为外汇市场是 OTC 市场,没有集中的订单簿。
股票和加密货币支持 ticker、depth、trade 三种频道。

REST vs WebSocket 使用边界图

完整使用路径示例

以港股行情监控系统为例:

Step 1:启动时拉取可用品种

GET /v1/symbols/available?market=HK&limit=100

目的:获取系统支持的港股品种,缓存到本地。


Step 2:页面展示用 Ticker + K 线

首页行情列表

GET /v1/market/ticker?symbols=700.HK,9988.HK,3690.HK

图表展示

GET /v1/market/kline?symbol=700.HK&interval=1d&limit=30

刷新策略:每 5-10 秒刷新一次 Ticker。
K 线按需加载(用户切换图表时才加载)。

刷新频率建议:

  • 太快(如每秒刷新)会增加服务器压力
  • 太慢(如 30 秒)数据实时性不足
  • 5-10 秒是平衡点

Step 3:关键模块用 WebSocket

仅在需要实时推送的场景建立 WebSocket 连接:

ws.send(JSON.stringify({
  cmd: 'subscribe',
  data: { channel: 'ticker', symbols: ['700.HK'] }
}));

退出实时监控页面时,必须取消订阅并关闭连接。
否则会导致连接数超限,影响新用户建立连接。

完整使用路径流程图

常见错误

1. 过度使用 WebSocket

错误做法:系统启动就建立 WebSocket,订阅所有品种。

问题:首页显示 50 个品种的行情。
订阅所有品种会导致用户量上升时服务器连接数超限。

正确做法:大部分场景使用 REST API。
仅在需要实时推送的模块使用 WebSocket。


2. K 线接口滥用

错误做法:每秒调用 K 线接口获取最新价。

问题:K 线接口是为历史数据设计的。
不是为实时价格设计的。
频繁调用浪费资源,且可能因时间对齐问题导致数据不准确。

正确做法:K 线用于历史数据和图表。
实时价格使用 Ticker 或 WebSocket。


3. Symbol 不缓存

错误做法:每次查询行情前都调用 /v1/symbols/available

问题:可用品种列表通常不会频繁变化。
每次都查询是浪费。

正确做法:启动时调用一次,缓存结果。
定期(如每天)更新。


4. Interval 选择不当

错误做法:不管什么场景都使用 1m(1 分钟 K 线)。

问题:1 分钟 K 线数据量大。
如果只是查看"最近一个月的走势",使用日 K 线即可。
使用 1 分钟 K 线浪费带宽,增加前端渲染压力。

正确做法

  • 实时图表:1m5m
  • 日内分析:1h
  • 中长期分析:1d

5. 混淆行情 API 与交易 API

错误做法:直接使用行情数据做下单决策。
不考虑延迟和数据完整性。

问题:行情 API 提供的是市场数据。
主要用于展示和分析。
交易操作(下单、撤单)需要对接交易所的交易 API。

正确做法:行情 API 用于数据展示和策略分析。
交易操作使用交易 API。

常见错误示意图

总结

使用行情 API 时,首先明确当前处于哪个阶段:

  • 启动系统
  • 展示页面
  • 实时监控

根据阶段选择合适的接口。
可以避免系统设计不合理导致的性能问题和维护困难。


系列说明

本文是「行情 API 的工程化使用方式」系列的第一篇。
后续将继续讲解:

  • WebSocket 实战:连接管理、心跳机制、数据补偿
  • K 线数据的正确使用方式:interval 选择、时间对齐、数据缓存策略
  • 行情系统的性能优化实践:从接口调用到前端渲染的完整优化方案
  • 多市场行情数据的统一处理:如何用一套代码处理港股、美股、外汇的差异

参考资料

本文基于 TickDB API v1.0.0 撰写。
完整接口参数说明、错误码处理、API 参考:

在现代前端开发中,图标库是必不可少的基础设施。然而,在 Vue 3 和 UniApp 的跨端开发场景下,我们常常面临各种痛点:

  • 😭 兼容性噩梦:Web 端好好的 SVG,到了小程序里就显示不出来。
  • 📦 体积臃肿:引入一个图标库,打包体积瞬间激增几兆。
  • 😫 开发体验差:没有类型提示,组件名靠猜,属性全靠试。
  • 🎨 样式难调:想改个颜色、大小,还要写一堆 CSS 覆盖。

如果你也遇到过这些问题,那么 VU-Icons 正是你一直在寻找的解决方案。


🌟 VU-Icons 是什么?

VU-Icons 是一个专为 Vue 3UniApp 打造的高质量 SVG 图标组件库。它不仅轻量、灵活,更完美解决了跨端兼容性问题,让你的开发效率倍增。

🌐 官网体验https://vuicons.qiboz.top/
📦 Giteehttps://gitee.com/zhangqibo920/uv-icons
📦 GitHubhttps://github.com/zhangqibo920/uv-icons

🔥 核心优势:为什么选择 VU-Icons?

1. 双端统一,无缝兼容

VU-Icons 的最大杀手锏是同时支持 Vue 3 和 UniApp

  • Vue 3:原生 SVG 渲染,性能极致。
  • UniApp:针对非 H5 平台(如微信小程序、App)进行了特殊优化,使用 rich-text 方案完美渲染 SVG,彻底告别“图标消失术”。

2. 真正的按需引入 (Tree Shaking)

担心引入图标库导致包体积变大?VU-Icons 完美支持 Tree Shaking
无论库里有多少个图标,只要你只用了一个 <VuHome />,打包时就只会包含这一个图标的代码。你的应用体积,由你掌控。

3. 极致的开发体验 (TypeScript)

作为一个现代组件库,TypeScript 支持是标配。
VU-Icons 内置了完整的 .d.ts 类型声明。在 VS Code 中,你能获得完美的组件名自动补全和属性提示,写代码就像在填空一样丝滑。

4. 高度可定制

告别繁琐的 CSS 覆盖,VU-Icons 提供了直观的 Props:

  • size:支持数字(如 24)和字符串(如 '2rem'),响应式布局更轻松。
  • color:支持 hex、rgb、颜色名,甚至默认继承父级 currentColor
  • spin:想要一个 Loading 效果?加上 spin 属性,任何图标都能变成旋转的加载动画!

快速上手

第一步:安装

npm install vu-icons
# 或者
yarn add vu-icons

第二步:使用(Vue 3 项目)

<script setup lang="ts">
// 直接按需引入,无需额外配置
import { VuHome, VuSearch, VuSettings } from 'vu-icons'
</script>

<template>
  <!-- 基础用法 -->
  <VuHome />
  
  <!-- 自定义颜色和尺寸 -->
  <VuSearch color="#1890ff" :size="32" />
  
  <!-- 一键开启旋转动画 -->
  <VuSettings spin color="#52c41a" />
</template>

第三步:使用(UniApp 项目)

<script setup lang="ts">
// 注意:UniApp 请从专用路径引入以确保兼容性
import { VuHome, VuUser } from 'vu-icons/uniapp'
</script>

<template>
  <view>
    <VuHome :size="40" color="#333" />
    <VuUser />
  </view>
</template>

进阶玩法

动态图标状态

结合 Vue 的响应式特性,你可以轻松制作交互效果:

<script setup>
import { ref } from 'vue'
import { VuRefresh } from 'vu-icons'

const loading = ref(false)
const refresh = () => {
  loading.value = true
  setTimeout(() => loading.value = false, 2000)
}
</script>

<template>
  <button @click="refresh">
    <!-- 点击时自动旋转 -->
    <VuRefresh :spin="loading" />
    刷新列表
  </button>
</template>

结语

VU-Icons 致力于成为 Vue 3 生态中最简单、最纯粹的图标解决方案。如果你厌倦了配置繁琐的 Font Icon,或者受够了跨端开发的兼容性坑,不妨试试 VU-Icons。

如果你觉得不错,欢迎在 Gitee 上点个 Star 支持一下!

👉 立即访问官网https://vuicons.qiboz.top/


为什么标准化要把均值设为0、方差设为1?

先说均值。均值就是平均数,所有观测值加起来除以个数。

μ是均值,n是数据点总数,xᵢ是每个数据点,所以均值就是数据的重心位置。比如均值是20,那20就是平衡点。这不是说所有点到20的距离相等而是说两边的"重量"刚好在20这个位置抵消掉。

而方差衡量的是数据有多分散,定义是每个值与均值偏差的平方的平均值。

n是数据点总数,xᵢ是每个数据点,μ是均值。

那均值为0有什么用?

可以把数据想象成坐标系里的一团“点云”。每个值减去均值(x — μ)之后,整团云就被平移到了原点位置。数据不再飘在某个角落而是以原点为中心分布。

这对很多机器学习算法都有好处,尤其是用梯度下降的时候。数据居中之后优化过程更平衡、收敛也更快。因为特征要是一开始就偏离原点很远,训练起来会麻烦不少。

那方差为1呢?

这是为了防止某个特征"欺负"其他特征。

举个例子:年龄和薪资两个特征,年龄范围10-70,薪资范围10,000-70,000。直接喂给模型的话,模型会觉得薪资比年龄重要1000倍(数字大嘛)。但这两个特征本来是独立的,凭什么薪资就更重要?

所以标准化就是除以标准差,让所有特征的方差都变成1。这样年龄和薪资就在同一个量级上了,变化幅度差不多。年龄有个小波动,不会因为薪资数字大就被模型无视掉。

可视化效果:

标准化之前,特征1(红色,小尺度)和特征2(蓝色,大尺度)放一起,红色那条几乎看不见。标准化之后,两个特征尺度一致,都能清晰显示出来。模型终于可以公平对待它们了。

什么时候需要标准化?逻辑回归、神经网络、KNN这类用梯度下降的算法,标准化影响最大。

总结一下:

均值为0让数据居中,方差为1让特征尺度统一。两者配合,算法学得更快,也不会偏心某个特征。至于什么时候该用标准化、什么时候该用MinMaxScaler,老实说我也还在摸索。

https://avoid.overfit.cn/post/957b1b35bc1047e185dab369ae8d84ed

作者:vaishnavi

前言

ELK 的一大缺点就是这东西最初是没有登录机制的,只要拿到了 url 地址,kibana 看板谁都可以访问一下。后来 ELK 自带了一套 xpack 进行登录认证,可是除了账户名密码登录这种最原始的方法,剩下的高级功能,比如 oauth, oidc, ldap ,统统都是收费的.....总不能给每个人都专门搞一个 kibana 账户名密码吧......

所以呢,这里有一个基于 casdoor 的 elk 鉴权解决方案,不要钱,开源的,还有人维护呢~。Casdoor 是一个基于 OAuth 2.0 / OIDC 的 UI 优先集中认证 / 单点登录 (SSO) 平台,而 casdoor/elk-auth-casdoor 这套解决方案,则是一个反向代理,他可以拦截所有未经登录的前往 elk 的 http 访问流量,并且引导未登录用户进行登录,而且这个反向代理对已登录用户是完全透明的。

仓库地址
https://github.com/casdoor/elk-auth-casdoor

QQ 群:645200447

如果您有更多相关的特殊需求可以加群,我们会有专人对接~ (可以联系 ComradeProgrammer )

casdoor 是什么

Casdoor 是一个基于 OAuth 2.0 / OIDC 的 UI 优先集中认证 / 单点登录 (SSO) 平台,简单点说,就是 Casdoor 可以帮你解决 用户管理 的难题,你无需开发用户登录注册等与用户鉴权相关的一系列功能,只需几个步骤,简单配置,与你的主应用配合,便可完全托管你的用户模块,简单省心,功能强大。

仓库地址: https://github.com/casbin/casdoor

演示地址: https://door.casbin.com/

官网文档: https://casdoor.org/

QQ 群:645200447

Casdoor 还支持 ldap ,saml 等诸多功能.....

Casdoor 目前作为 Casbin 社区项目统一使用的鉴权平台,项目已开源,希望得到大家的一些建议和 Star~,我们会及时跟进反馈并改正问题哒

Casdoor 又有哪些特性?

  • 支持普通的账户密码注册登录,也支持各种常见的第三方认证,例如 GitHub 、Facebook 、Google 、Wechat 、QQ 、LinkedIn 等等,截止目前共 9 个平台,并在不断听取用户建议对更多的平台提供支持。
  • 管理方便。Casdoor 内部将模块分为了 5 大类,Organization 、User 、Application 、Token 和 Provider 。可以同时接入多个组织,组织下有不同应用,用户可以通过应用或组织分类,单独管理任何组织、应用或用户的 Token 令牌,轻松管理复杂系统,目前已部署在 Casbin 社区各种系统当作鉴权平台。
  • 自定义程度高。Casdoor 可以随意修改登录方式,例如是否允许密码或第三方登录,自定义应用的注册项数量,是否启用两步验证,以及是否允许各个 Provider 登录、注册等等,高度可插拔。
  • 具备 Swagger API 文档。清晰的 API 介绍,无需阅读源代码即可直接方便调用各个 API 接口,提供定制化功能。
  • 前后端分离架构,部署简单。作为统一认证平台,除了性能,稳定性,新特性之外,易用性也是考量的重要标准,Casdoor 后端使用 Golang 语言开发,前端使用 React.js 框架,使用者只需启动后端服务,并将前端工程文件打包,即可直接使用,操作简单,上手难度低。
    ...

换机登录 telegram ,+1 号码登录弹框要求绑定邮箱,然后顺利登录了,+86 号码登录也要求绑定邮箱,输完邮箱就要求买一个礼拜会员,我在电脑和老手机都有登录,也看了最近的帖子,但我既无法通过其他设备收码,也无法创建 passkey ,无奈之下只得付了钱

付钱之后,进入手机号收码界面,但还是收不到码,失败两次後变成了电话接码,等了半天收到一个联通的短信,才发现国际通话被拦截了,又到联通那把国际拦截关掉。再登录就完全没反应了,来回反复登录几次,才终于把通过其他设备接码逼出来,登了进去

进去之后发现那一个礼拜的会员完全没有给我,如果不给我会员那不就相当于花一刀多买一条短信?更别说我根本也没收到任何东西

一怒之下在苹果那提交退款申请,刚刚收到了退款,舒服了

顺带一提。最开头那个+86 绑定邮箱完全没用,+1 的号码可以在设置里看到登录邮箱的选项,但+86 登录进去後是没有这个选项的

最近写代码拉满了,Cursor 有时候抽疯回答不是很好。去看了下 cc 的用法隔壁 v 站也推荐 cc 写代码质量很高,就找了很多 cc 的中转站试用下来推荐。

  1. https://aicoding.sh/i/VqUqnn (评分 5,最近一周开始用没有挂过,自认为很稳定。注册送 3000 积分大概半天的量吧)
  2. https://www.88code.org/register?ref=33STTY (评分 3,注册当天就挂了大概第二天恢复,但是注册可以找 QQ 群客服送一个月限额)
  3. https://privnode.com/ (评分 4,也比较稳定没遇到挂过。但是速度没第一个快,注册送 $3 差不多也是半天的量)
  4. https://cubence.com/signup?code=SC436OLS (评分 ----,正在试用中,大概率和第一个有得一拼,注册也是送 $3)

最后搭配 cc-switch 无缝切换很好,价格上来说第一个应该是最贵的。其他的貌似可以买额度不用包月,但是不稳定。

如果大家还有其他中转站也可以推荐下,试用完了后续就准备买额度用着了。重要是稳定!!!

aff 大家如果要试用可以用下我的哈哈,这样我还能在试用一段时间 🤔

这几天突然被告知有直系亲属患了肺癌,然后又被告知之前已经有亲属因为肺癌去世。

这两天的陪护经历,医院医生也直言他就是基因不好,比常人更易患癌。

一开始很焦虑,老想着做一个癌症易感基因检测,但是转念一想,自己有这个易感基因基本上是板上钉钉的,就算每有,也不可能放弃每年主动去做早筛了,换句话说,无论结果出来有没有肺癌易感基因,以后都必然是防范到死的。

这么一想,感觉这种检测不做也行。

想咨询下 V 友这块,我该不该去做,基因检测费用也挺高的,和遗传病基因检测还不同,这个相当于只是易感筛查,专业一次的检测据说起码 5000 多的专项检测,全面的要上万多。