作者归档:songtianlun

2025-10-05

文字表达能力

今天看到这个 帖子 ,很有感触。现在很多工作为了快,都是先用 AI 打个底稿,再人工优化。久而久之写作水平就下降了。 此前一直想要多写点东西,但总是拘泥于形式不敢下手。现在看来再不下手就晚了,敢在自己写作水平下降之前多写点东西。无所谓什么,写就是了。

探索手机发送公众号的工作流

先用最简单的方式跑通,比如今天这个。

优秀的 SubReddit 清单

SubReddit 清单

  • SaaS 类
    • r/B2BSaaS(B2B SaaS 人群集中,~8k 成员)
    • r/NoCodeSaaS(无代码 SaaS,~22k 成员)
    • r/micro_saas(微型 SaaS,~10k 成员)
    • r/indiebiz(小体量&个人生意,~24k 成员)
    • r/SaaS(讨论/反馈/支持,~95k 成员)
    • r/startup_resources(工具/模版/手册,~24k 成员)
    • r/LaunchMyStartup(早期发布与反馈,~2k 成员)
    • r/ProductHunters(PH 发现与讨论,~23k 成员)
    • r/saasapps(平台/生态应用,成员数小)
    • r/BootstrappedSaaS(自筹/自启动,~935 成员)
  • 创业类
    • r/startups(最大创业社区,~1.2M 成员)
    • r/SideProject(副业/项目展示,~478k 成员)
    • r/indiehackers(独立开发者,~24k 成员)
    • r/EntrepreneurRideAlong(创业旅程分享,~517k 成员)
    • r/thesidehustle(点子与建议,~79k 成员)
    • r/growmybusiness(增长与扩张,~51k 成员)
    • r/startup(创业创建与增长,~300k 成员)
    • r/startups_promotion(集中自荐区,~3.1k 成员)
    • r/roastmystartup(犀利真反馈,成员数小)
    • r/sweatystartup(轻松创业讨论,成员数小)
    • r/SmallBusiness(日常经营与建议,成员数大)
    • r/Entrepreneur(泛创业与商业,成员数大)
  • 营销类
    • r/SaaSMarketing(从策略到落地,~11k 成员)
    • r/ProductMarketing(定位/叙事/布,~18k 成员)
    • r/MarketingHelp(众包建议与诊断,~16k 成员)
    • r/ecommerce_growth(电商增长(可迁移),~9k 成员)
    • r/email(送达率/MarTech,~11k 成员)
    • r/EmailOutreach(冷邮件技巧,~1k 成员)
    • r/AskGrowth(增长问答,数百成员)
    • r/Marketing(综合营销,成员数大)
    • r/AskMarketing(营销问答,成员数中)
    • r/SocialMedia(社媒策略,成员数大)
    • r/CopyWriting(文案/转化,成员数中)
    • r/Advertising(投放策略,成员数中)
    • r/WebMarketing(SEO/内容,成员数大)
    • r/EmailMarketing(邮件营销,成员数中)
    • r/Sales(销售与漏斗,成员数大)
    • r/PlugYourProduct(直推(先看规则),成员数小)
    • r/GrowthHacking(增长与病毒,成员数中)
  • 技术类
    • r/NextGenAITool(AI 工具展示,~4k 成员)
    • r/webdev(Web 开发,~1.4M 成员)
    • r/JAMstack_dev(落地页与性能,~2k 成员)
    • r/pocketbase(快速后端,~3k 成员)
    • r/SQLServer(多租户/性能,~58k 成员)
    • r/lowcode(流程自动化,~3k 成员)
    • r/DesignCritiques(设计求评,~85k 成员)
    • r/InternetIsBeautiful(创意展示,~16.2M 成员)
  • 测试类
    • r/TestMyApp(早期用户与反馈,~6k 成员)
    • r/AlphaandBetausers(寻找测试者,~10k 成员)
  • 支付类
    • r/stripe(订阅/计费,~19k 成员)
    • r/PaymentProcessing(网关/拒付,~5k 成员)
  • 运营类
    • r/FPandA(预算/收入模型,~53k 成员)
    • r/CustomerService(流程与工具,~39k 成员)
    • r/CustomerValue(价值定价/CS 对齐,成员数小)
    • r/CustomerSuccessHub(CS 社区,成员数小)
  • 融资类
    • r/VentureCapital(基金/募资洞见,成员数大)
    • r/Crowdfunding(众筹策略,成员数中)
    • r/Kickstarter(众筹项目,成员数大)
    • r/startupinvesting(早期投资,~1k 成员)
    • r/SaaSidea(点子分享,成员数小)
    • r/AISaaSHunter(AI SaaS 展示,成员数小)
    • r/LLMO_SaaS(LLM SEO 分发,数百成员)

Reddit增长地图

Refs

云部署平台全面对比:Railway vs Render vs 其他主流方案(2025年版)

随着 Heroku 免费套餐的终止,开发者们纷纷寻找新的云部署解决方案。本文将深入对比 Railway、Render 以及其他主流平台,帮你选择最适合项目需求的部署方案。

平台概述

Railway

Railway 是一个注重开发者体验的现代化平台,强调快速部署和简洁界面。它采用用量计费模式,通过直观的可视化画布管理基础设施。

核心优势:

  • 快速迭代和部署
  • 直观的可视化界面
  • 实时协作功能
  • 用量计费,适合流量不稳定的应用

Render

Render 定位为生产就绪的云平台,提供结构化的基础设施管理和可预测的定价模式。

核心优势:

  • 内置后台任务支持
  • 预测性定价
  • 生产环境默认配置
  • 丰富的部署配置选项

其他主流平台

  • Vercel: 专注前端和 Jamstack
  • Fly.io: 全球分布式部署
  • DigitalOcean App Platform: 传统云厂商的 PaaS 方案
  • Heroku: 老牌 PaaS 平台

详细功能对比表

功能特性 Railway Render Vercel Fly.io DigitalOcean Heroku
免费套餐 ❌ 已取消 ✅ 750小时/月 ✅ 静态站点 ✅ 基础用量 ✅ 3个静态应用 ❌ 已取消
定价模式 用量计费 实例计费 请求计费 用量计费 混合计费 实例计费
起步价格 $5/月+用量 $7/月 $20/月 $5/月 $5/月 $7/月
自动扩展 ✅ 动态资源分配 ✅ 手动配置 ✅ 边缘计算 ✅ 多区域 ✅ 垂直/水平 ✅ 传统扩展
后台任务 ⚠️ 需手动配置 ✅ 原生支持 ❌ 无 ✅ 支持 ✅ 支持 ✅ 支持
数据库 ✅ 多种数据库 ✅ PostgreSQL/Redis ❌ 外部集成 ✅ 卷存储 ✅ 托管数据库 ✅ 丰富插件
多区域部署 ✅ 全球边缘 ⚠️ 有限区域 ✅ 全球 CDN ✅ 多区域优势 ✅ 多数据中心 ✅ 多区域
容器支持 ✅ Docker ✅ Docker ⚠️ 轻量容器 ✅ 全容器化 ✅ Docker ✅ 容器
CI/CD ✅ Git 集成 ✅ Git 集成 ✅ Git 集成 ✅ CLI 驱动 ✅ Git 集成 ✅ Git 集成
监控日志 ✅ 基础监控 ✅ 详细日志 ✅ 分析工具 ✅ CLI 工具 ✅ 完整监控 ✅ 日志聚合

支持的编程语言和技术栈

🔧 编程语言支持对比

语言/技术 Railway Render Vercel Fly.io DigitalOcean Heroku
JavaScript/Node.js ✅ 完全支持 ✅ 完全支持 ✅ 原生优化 ✅ 完全支持 ✅ 完全支持 ✅ 完全支持
TypeScript ✅ 完全支持 ✅ 完全支持 ✅ 原生支持 ✅ 完全支持 ✅ 完全支持 ✅ 完全支持
Python ✅ Django/Flask ✅ Django/Flask ⚠️ 社区运行时 ✅ 完全支持 ✅ 完全支持 ✅ 完全支持
Go ✅ 完全支持 ✅ 完全支持 ⚠️ 社区运行时 ✅ 完全支持 ✅ 完全支持 ✅ 完全支持
Rust ✅ 完全支持 ✅ 完全支持 ⚠️ 社区运行时 ✅ 完全支持 ✅ 完全支持 ✅ 完全支持
Java ✅ Spring Boot ✅ Spring Boot ❌ 不支持 ✅ 完全支持 ✅ 完全支持 ✅ 完全支持
PHP ✅ Laravel ✅ 完全支持 ⚠️ 社区运行时 ✅ 完全支持 ✅ 完全支持 ✅ 完全支持
Ruby ✅ Rails ✅ Rails ❌ 不支持 ✅ 完全支持 ✅ 完全支持 ✅ 完全支持
C#/.NET ✅ ASP.NET Core ✅ 完全支持 ❌ 不支持 ✅ 完全支持 ✅ 完全支持 ✅ 完全支持
Elixir ✅ Phoenix ✅ Phoenix ❌ 不支持 ✅ 完全支持 ✅ 完全支持 ✅ 完全支持
Dart ✅ 支持 ⚠️ 有限 ❌ 不支持 ✅ 支持 ⚠️ 有限 ⚠️ 有限

🚀 前端框架支持

框架 Railway Render Vercel Fly.io DigitalOcean 最佳选择
React ✅ 原生优化 Vercel
Next.js ✅ 官方框架 Vercel
Vue.js Railway/Render
Nuxt.js ✅ 优化 Vercel
Svelte Railway/Render
SvelteKit ✅ 优化 Vercel
Angular Railway/Render
Astro ✅ 优化 Vercel

⚙️ 后端框架支持

框架 Railway Render Vercel Fly.io DigitalOcean 推荐理由
Express.js ✅ 优秀 ✅ 优秀 ✅ 函数形式 ✅ 优秀 ✅ 优秀 全平台通用
FastAPI ✅ 优秀 ✅ 优秀 ⚠️ 有限 ✅ 优秀 ✅ 优秀 Railway/Render
Django ✅ 优秀 ✅ 优秀 ❌ 不支持 ✅ 优秀 ✅ 优秀 Railway/Render
Flask ✅ 优秀 ✅ 优秀 ⚠️ 函数形式 ✅ 优秀 ✅ 优秀 Railway/Render
Spring Boot ✅ 优秀 ✅ 优秀 ❌ 不支持 ✅ 优秀 ✅ 优秀 Railway/Fly.io
Rails ✅ 优秀 ✅ 优秀 ❌ 不支持 ✅ 优秀 ✅ 优秀 Railway/Render
Laravel ✅ 优秀 ✅ 优秀 ⚠️ 社区 ✅ 优秀 ✅ 优秀 Railway/Render
ASP.NET Core ✅ 优秀 ✅ 优秀 ❌ 不支持 ✅ 优秀 ✅ 优秀 Railway/Fly.io
Phoenix ✅ 优秀 ✅ 优秀 ❌ 不支持 ✅ 优秀 ✅ 优秀 Fly.io

🗄️ 数据库支持

数据库 Railway Render Vercel Fly.io DigitalOcean
PostgreSQL ✅ 托管服务 ✅ 托管服务 🔗 外部集成 ✅ 卷存储 ✅ 托管服务
MySQL ✅ 托管服务 ⚠️ 外部 🔗 外部集成 ✅ 卷存储 ✅ 托管服务
MongoDB ✅ 托管服务 ⚠️ 手动配置 🔗 外部集成 ✅ 卷存储 ✅ 托管服务
Redis ✅ 托管服务 ✅ 托管服务 🔗 外部集成 ✅ 卷存储 ✅ 托管服务
SQLite ✅ 卷存储 ✅ 卷存储 ❌ 不支持 ✅ 卷存储 ✅ 卷存储

详细定价对比

Railway 定价结构

试用计划:$5 一次性额度(30天有效)
爱好计划:$5/月 + 用量费用
专业计划:$20/月 + 用量费用

用量计费:
- CPU:$20/CPU/月
- 内存:$10/GB/月
- 网络:$0.10/GB

Render 定价结构

免费计划:750实例小时/月(15分钟无活动后休眠)
入门计划:$7/月(512MB RAM,0.5 CPU)
标准计划:$25/月(2GB RAM,1 CPU)
专业计划:$85/月(8GB RAM,4 CPU)

Vercel 定价结构

Hobby:免费(100万请求/月)
Pro:$20/月/用户(更高限额)
Team:$40/月/用户(团队协作)
Enterprise:自定义定价

Fly.io 定价结构

免费额度:3个共享CPU实例 + 3GB持久存储
付费:按实际用量计费
- CPU:约$0.02/CPU小时
- 内存:约$0.0015/MB小时

DigitalOcean App Platform 定价结构

免费:3个静态站点应用
基础:$5/月起(共享CPU)
专业:$12/月起(专用CPU)
企业:自定义配置

🎯 技术栈特定优化

JavaScript/TypeScript 生态

  • Vercel: 为 Next.js 和 React 提供原生优化,支持边缘函数和 SSR
  • Railway: 自动检测并优化 Node.js 应用,实时协作调试
  • Render: 提供完整的 JavaScript 栈支持,包括静态站点和 API

Python 开发

  • Railway: 支持 Flask 和 Django,使用 Railpack 构建系统自动检测框架
  • Render: 支持 Python、Django、Flask 等主流框架
  • DigitalOcean: 提供完整的 Python 栈支持和托管数据库

全栈开发

  • Railway: 支持从 PostHog 到 Next.js 的各种模板,包括 AI 工具如 vLLM
  • Fly.io: 支持所有语言和框架,提供全面的文档和指南
  • Render: 专注于生产就绪的全栈应用部署

企业级应用

  • DigitalOcean: 支持 Node.js、Python、Django、Go 和 PHP,提供统一的部署环境
  • Fly.io: 适合需要全球分布和高性能的企业应用
  • Railway: 适合需要快速迭代的中小企业

🔥 2025年技术趋势对应

AI/ML 集成应用

  • Python + FastAPI 栈: FastAPI 在2025年增长5个百分点,成为构建高性能 API 的首选
  • 推荐平台: Railway(AI模板丰富)或 Render(生产稳定)

边缘计算和全球分发

  • Next.js + Vercel: 边缘函数和全球 CDN 优化
  • Fly.io: 全球分布式架构,适合边缘计算

容器化优先

  • Docker 采用: Docker 在2025年使用率增长17个百分点,成为近乎通用的工具
  • 推荐平台: Fly.io(全容器化)或 Railway(Docker 原生支持)

现代前端框架

  • React 生态: 仍然是主流选择,React 凭借虚拟 DOM 和组件化架构继续领先
  • 新兴框架: Svelte 以其编译时优化和更高性能获得关注

使用场景推荐

选择 Railway 的情况

最适合:

  • 快速原型开发和迭代
  • JavaScript/TypeScript 项目(Node.js、React、Next.js)
  • Python 应用(Django、Flask、FastAPI)
  • 流量波动较大的应用
  • 重视开发体验和协作的团队
  • AI/ML 项目集成(提供 vLLM、DeepSeek 等 AI 模板)
  • 预算敏感的小型项目

🔧 技术栈优势:

  • 使用 Railpack 自动检测框架
  • 支持 PostgreSQL、MySQL、MongoDB、Redis 托管服务
  • 实时协作和可视化部署界面

不适合:

  • 需要复杂后台任务的应用
  • 要求可预测成本的企业应用
  • PHP 或 Ruby 重度依赖项目

选择 Render 的情况

最适合:

  • 生产环境应用
  • 全栈 Web 应用(支持所有主流语言)
  • 需要后台任务和定时作业
  • Django、Rails、Laravel 等传统框架项目
  • 要求稳定运行的服务
  • 预算可预测的项目

🔧 技术栈优势:

  • 原生支持 PostgreSQL 和 Redis 托管服务
  • 完整的 Docker 支持和生产级默认配置
  • 支持 Python、Ruby、Node.js、Go、PHP 等

不适合:

  • 极度价格敏感的个人项目
  • 需要全球化分布的应用
  • MongoDB 重度依赖项目(需手动配置)

选择 Vercel 的情况

最适合:

  • 前端应用和静态网站
  • Next.js、React、Vue.js、Svelte 项目
  • JAMstack 架构应用
  • 需要极致加载速度和全球 CDN 的应用
  • 边缘计算和 Serverless 函数

🔧 技术栈优势:

  • Next.js 官方平台,提供原生优化
  • 支持 React、Vue、Svelte、Astro 等现代前端框架
  • 边缘函数支持多种运行时

不适合:

  • 重后端逻辑的应用
  • Django、Rails 等传统框架项目
  • 需要持久化数据库的服务
  • PHP、Java、C# 项目(缺乏原生支持)

选择 Fly.io 的情况

最适合:

  • 需要全球分布的应用
  • 对延迟敏感的服务
  • 容器化优先的项目
  • Elixir/Phoenix 实时应用
  • 需要边缘计算的应用
  • 企业级微服务架构

🔧 技术栈优势:

  • 支持所有编程语言和框架
  • 全容器化部署模式
  • Phoenix 框架的最佳选择平台
  • 支持复杂的网络配置

不适合:

  • Docker 新手团队
  • 需要简单部署流程的项目
  • 预算紧张的个人开发者
  • 不需要全球分布的简单应用

选择 DigitalOcean App Platform 的情况

最适合:

  • 已使用 DigitalOcean 生态的项目
  • 多语言混合项目(Node.js + Python + PHP)
  • 需要传统云服务集成
  • 预算有限但需要专业功能
  • 中小型企业全栈应用

🔧 技术栈优势:

  • 统一环境支持 Node.js、Python、Django、Go、PHP
  • 托管数据库服务(PostgreSQL、MySQL、Redis)
  • 与 DigitalOcean Droplets 和其他服务无缝集成

不适合:

  • 需要最新功能和前沿技术的项目
  • 极简部署需求
  • 高度定制化网络配置

成本效益分析

低流量场景(< 1000 用户/月)

  1. DigitalOcean App Platform – $5/月,最经济
  2. Render 免费层 – $0/月,但有限制
  3. Fly.io – 免费额度足够使用
  4. Railway – $5-15/月,视用量而定

中等流量场景(1000-10000 用户/月)

  1. Render – $7-25/月,可预测成本
  2. Railway – $10-30/月,视实际用量
  3. DigitalOcean – $12-40/月
  4. Fly.io – $15-50/月

高流量场景(10000+ 用户/月)

  1. Fly.io – 全球分布优势
  2. Railway – 弹性用量计费
  3. Render – 固定成本可控
  4. DigitalOcean – 企业级功能

技术考量

开发者体验排名

  1. Railway – 最直观的界面和协作功能
  2. Vercel – 前端开发者首选
  3. Render – 平衡的开发体验
  4. DigitalOcean – 传统但完善
  5. Fly.io – CLI 优先,学习曲线陡峭

生产环境成熟度

  1. Heroku – 最成熟稳定
  2. Render – 生产环境优化
  3. DigitalOcean – 企业级可靠性
  4. Fly.io – 技术先进但相对年轻
  5. Railway – 快速发展中

扩展性和性能

  1. Fly.io – 全球边缘分布
  2. Vercel – 前端性能优化
  3. Railway – 灵活的资源分配
  4. Render – 传统但稳定的扩展
  5. DigitalOcean – 可预测的性能

迁移建议

从 Heroku 迁移

  • 首选 Render:最相似的体验和功能
  • 次选 Railway:更现代的界面和定价
  • 考虑 DigitalOcean:如果需要更多控制

从传统云服务迁移

  • 首选 Railway:最简单的迁移过程
  • 次选 Fly.io:如果已经容器化
  • 考虑 Vercel:如果是前端项目

总结建议

2025年云部署平台选择策略:

🎯 快速开始和原型验证:选择 Railway

  • 最直观的部署体验
  • 灵活的用量计费
  • 适合快速迭代

🏭 生产环境和企业应用:选择 Render

  • 可预测的成本结构
  • 内置生产级功能
  • 稳定可靠的运行环境

🚀 前端和静态网站:选择 Vercel

  • 最佳的前端开发体验
  • 全球 CDN 优化
  • Next.js 原生支持

🌍 全球化和性能优先:选择 Fly.io

  • 全球分布式部署
  • 边缘计算能力
  • 容器化优势

💰 预算敏感的项目:选择 DigitalOcean App Platform

  • 最具价格优势
  • 丰富的云服务生态
  • 企业级基础设施

最终建议:

🎯 按技术栈选择:

  • JavaScript/TypeScript 项目: Vercel(前端优先)或 Railway(全栈开发)
  • Python 项目: Railway(快速迭代)或 Render(生产稳定)
  • 多语言项目: DigitalOcean App Platform(统一管理)或 Fly.io(容器化)
  • 传统企业框架: Render(Java、C#、PHP 支持完整)
  • AI/ML 应用: Railway(AI 模板丰富)配合 Python + FastAPI
  • 实时应用: Fly.io(Elixir/Phoenix 最佳选择)

📊 按项目规模选择:

  • 个人项目/原型: Railway(开发体验)或 DigitalOcean(成本控制)
  • 初创公司: Railway(快速迭代)或 Vercel(前端优先)
  • 成长期企业: Render(稳定性)或 Fly.io(全球分布)
  • 大型企业: DigitalOcean(成本控制)或 Fly.io(性能优先)

🚀 按开发阶段选择:

  • 快速原型验证: Railway + JavaScript/Python 栈
  • MVP 开发: Render + Django/Rails 或 Vercel + Next.js
  • 生产环境部署: Fly.io + Docker 或 DigitalOcean + 多服务架构
  • 企业级应用: DigitalOcean/Fly.io + 微服务架构

选择平台时,请综合考虑项目的技术栈、团队熟悉度、预算约束和长期技术发展规划。建议先在免费套餐上测试主要功能,确认技术栈兼容性后再做最终决定。

整理了一个 AI 提示词库

大模型的能力越来越强,但是如何发挥大模型真正的实力?

这是我一直在思考的问题,在平常的使用过程中很容易发现,提示词的使用技巧对于生成结果的质量至关重要。多看看优秀的提示词,还能启发我们利用大模型的更多用法。

在网上看到许多优秀的提示词仓库,但一般都是针对某个模型或场景的,一直想整理一个更方便易读,根据模态、模型分类,从各处搜集优秀的提示词汇集到一处的仓库。

于是最近制作了这个网站:https://prmbr.com/

一个精选提示词库,包括 Text-To-Text, Text-To-Image, Text-To-Video 等提示词用法,还有针对 Nano Banana GPT-Image-1 等模型的专门分区,内容全部来自于各大开源的 Prompt 仓库、社交媒体、网站,以及我在各种地方偶然看到的内容。

初期内容还比较有限,后期逐渐完善,分享给大家。

代码仓库已经开源,可以参与共建:https://github.com/songtianlun/awesome-prompts

让 LLM 看到真实世界的 Playwright MCP

Playwright MCP 是一个模型上下文协议(MCP)服务器,使用 Playwright 提供浏览器自动化功能。该服务器使 LLM 能够通过结构化的可访问性快照与网页交互,从而绕过对屏幕截图或视觉调整模型的需求。

使用方法

以 codex 为例,创建或编辑配置文件 ~/.codex/config.toml 并添加:

[mcp_servers.playwright]
command = "npx"
args = ["@playwright/mcp@latest"]

References

磁盘占用分析利器 ncdu

现在使用 ncdu 的话,只需要执行一次就可以查询目录大小并排序,且删除文件也很方便,不会出错。

基本用法

安装:

# ubuntu
sudo apt install ncdu
# centos
sudo yum install ncdu
# macOS
brew install ncdu

使用

# 统计当前所在目录及子目录的文件占用情况
ncdu

# 统计指定的 /data 目录
ncdu /data

# 将 /data 目录的情况输出到 ~/ncdu.txt
ncdu /data -o ~/ncdu.txt

# 加载本地根据,而不是进行实时统计
ncdu -f ~/ncdu.txt 

References

地图标记和兴趣点分享软件合集

从学 GIS 开始,就一直想做/找一个地图兴趣点标记、分享软件。之前也做过,但是苦于时间、运维成本太高,就只能放在那里了。直到最近发现自己总是会碰到这种,需要标记和分享兴趣点的需求。特别是多点规划、形成规划的时候,有一个这样的软件比直接看地图要方便太多。

依稀记得之前用过一个 exping,但是遗憾的发现已经于 2024年12月31日停止服务 了,很可惜,但也在意料之中吧。因为这个软件虽然设计很好,但是一直以来都感觉卡卡的,动画很不流畅,即使在 2025年的今天打开也是如此。所以也不意外吧。这是一个小众的需求,但是投入了太多的成本,做了一个太重的东西出来。

今天用 Claude 分析了类似的地图标记和兴趣点分享软件,感觉分析的不错,基本我了解到的就是这些,就在此记录一下。

国内应用

1. 识途(微信小程序)

已更名为 路敢敢 ,初步看了一下体验不错,后续考虑用一下。

  • 提供地图定位、路线规划、在线协作、美好瞬间个性化标记等实用功能,每一次创作的计划可以通过发布社区分享出去
  • 微信小程序,使用便捷

2. 飞鸿踏雪

  • 可以记录轨迹,还可以记录照片、视频、录音、甚至文字,直接标在地图上
  • 记录说过的话、走过的路、看过的风景、想过的事,名字取自苏东坡诗词
  • 支持多种媒体内容标记

3. 兰图绘

  • 方便易用的地图标绘云平台,适合各种企业和个人,支持团队协作绘图
  • 支持点位路线标绘、区域范围标绘

4. 钉图易

  • 让您在地图上自由绘制点、线以及面元素,多位用户可在地图上同时进行标绘,数据实时互通并保持同步
  • 更偏向商业和团队协作使用

国际应用

5. Google My Maps

  • 可以通过搜索地点或直接在地图上绘制来添加重要地点,一张地图最多可以拥有10000个功能项
  • Google生态系统,功能强大

6. Google Earth

  • 使用创作工具,可以在地图上绘图,添加照片和视频,自定义视图,并与他人分享和协作
  • 3D地球视图,视觉效果出色

专业工具

7. 图新地球

  • 标绘编辑功能模块,适用于河湖标绘、测绘、规划设计、林业农业、疫情防控等多种场景
  • 更偏向专业测绘和工程应用

足迹记录类

  • 世界迷雾 – 探索世界的游戏化地图应用
  • 一生足迹 – 自动记录个人轨迹
  • 足迹地图 – 旅行足迹统计和生成

特点对比:

  • 个人创作向:exping、飞鸿踏雪、识途
  • 团队协作向:钉图易、兰图绘
  • 国际化:Google My Maps、Google Earth
  • 专业应用:图新地球、ArcGIS
  • 足迹记录:世界迷雾、一生足迹

最接近exping的替代品应该是识途(微信小程序)和飞鸿踏雪,它们都支持个人创作、社区分享,以及丰富的标记功能。

总结

本为开头和结尾非 AI 生成。 目前看最好用的应该是 识途(微信小程序),后续考虑用一下。这种需求在微信生态下应该是最合适的,很方便分享,也不需要考虑多端兼容问题。也算是一个技术选型的典范了吧。

自建 gitlab 徽标问题导致项目 500 问题解决

问题

最近内部 gitlab 某些项目打开就 500 了, 看 gitlab 报错日志如下:

gitlab  | {"method":"GET","path":"/xxx/xxx","format":"html","controller":"ProjectsController","action":"show","status":500,"time":"2025-08-28T00:51:41.511Z","params":[{"key":"namespace_id","value":"xxx"},{"key":"id","value":"xxx"}],"remote_ip":"10.17.7.63","user_id":74,"username":"xxxgitlab | {"method":"GET","path":"/xxx/xxx","format":"html","controller":"ProjectsController","action":"show","status":500,"time":"2025-08-28T00:51:41.511Z","params":[{"key":"namespace_id","value":"xxx"},{"key":"id","value":"xxx"}],"remote_ip":"10.17.7.63","user_id":74,"username":"xxx","ua":"Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0","correlation_id":"01K3Q2F5DXP8Y33B25TW9SSMYM","meta.user":"xxx","meta.project":"xxx/xxx","meta.root_namespace":"storage","meta.caller_id":"ProjectsController#show","meta.remote_ip":"10.17.7.63","meta.feature_category":"projects","meta.client_id":"user/74","redis_calls":21,"redis_duration_s":0.007123,"redis_read_bytes":2997,"redis_write_bytes":2370,"redis_cache_calls":20,"redis_cache_duration_s":0.006591,"redis_cache_read_bytes":2816,"redis_cache_write_bytes":1035,"redis_shared_state_calls":1,"redis_shared_state_duration_s":0.000532,"redis_shared_state_read_bytes":181,"redis_shared_state_write_bytes":1335,"db_count":41,"db_write_count":0,"db_cached_count":10,"cpu_s":2.291446,"mem_objects":394125,"mem_bytes":52397272,"mem_mallocs":198648,"mem_total_bytes":68162272,"queue_duration_s":0.009214,"exception.class":"Rack::Timeout::RequestTimeoutException","exception.message":"Request ran for longer than 60000ms","exception.backtrace":["lib/gitlab/url_blocker.rb:113:in `getaddrinfo'","lib/gitlab/url_blocker.rb:113:in `get_address_info'","lib/gitlab/url_blocker.rb:48:in `validate!'","app/validators/addressable_url_validator.rb:83:in `validate_each'","app/models/badge.rb:43:in `build_rendered_url'","app/models/badge.rb:36:in `rendered_image_url'","app/models/badges/project_badge.rb:15:in `rendered_image_url'","app/views/projects/_home_panel.html.haml:93","app/views/projects/_home_panel.html.haml:89","app/views/projects/_home_panel.html.haml:87","app/views/projects/show.html.haml:14","app/controllers/application_controller.rb:128:in `render'","app/controllers/application_controller.rb:538:in `block in allow_gitaly_ref_name_caching'","lib/gitlab/gitaly_client.rb:341:in `allow_ref_name_caching'","app/controllers/application_controller.rb:537:in `allow_gitaly_ref_name_caching'","app/controllers/application_controller.rb:487:in `set_current_admin'","lib/gitlab/session.rb:11:in `with_session'","app/controllers/application_controller.rb:478:in `set_session_storage'","lib/gitlab/i18n.rb:99:in `with_locale'","lib/gitlab/i18n.rb:105:in `with_user_locale'","app/controllers/application_controller.rb:472:in `set_locale'","app/controllers/application_controller.rb:466:in `set_current_context'","lib/gitlab/metrics/elasticsearch_rack_middleware.rb:16:in `call'","lib/gitlab/middleware/rails_queue_duration.rb:33:in `call'","lib/gitlab/metrics/rack_middleware.rb:16:in `block in call'","lib/gitlab/metrics/web_transaction.rb:21:in `run'","lib/gitlab/metrics/rack_middleware.rb:16:in `call'","lib/gitlab/middleware/speedscope.rb:13:in `call'","lib/gitlab/request_profiler/middleware.rb:17:in `call'","lib/gitlab/jira/middleware.rb:19:in `call'","lib/gitlab/middleware/go.rb:20:in `call'","lib/gitlab/etag_caching/middleware.rb:21:in `call'","lib/gitlab/middleware/multipart.rb:172:in `call'","lib/gitlab/middleware/read_only/controller.rb:50:in `call'","lib/gitlab/middleware/read_only.rb:18:in `call'","lib/gitlab/middleware/same_site_cookies.rb:27:in `call'","lib/gitlab/middleware/handle_malformed_strings.rb:21:in `call'","lib/gitlab/middleware/basic_health_check.rb:25:in `call'","lib/gitlab/middleware/handle_ip_spoof_attack_error.rb:25:in `call'","lib/gitlab/middleware/request_context.rb:21:in `call'","config/initializers/fix_local_cache_middleware.rb:11:in `call'","lib/gitlab/middleware/rack_multipart_tempfile_factory.rb:19:in `call'","lib/gitlab/metrics/requests_rack_middleware.rb:74:in `call'","lib/gitlab/middleware/release_env.rb:12:in `call'"],"db_duration_s":0.23847,"view_duration_s":0.0,"duration_s":73.05203}","ua":"Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0","correlation_id":"01K3Q2F5DXP8Y33B25TW9SSMYM","meta.user":"xxx","meta.project":"xxx/xxx","meta.root_namespace":"storage","meta.caller_id":"ProjectsController#show","meta.remote_ip":"10.17.7.63","meta.feature_category":"projects","meta.client_id":"user/74","redis_calls":21,"redis_duration_s":0.007123,"redis_read_bytes":2997,"redis_write_bytes":2370,"redis_cache_calls":20,"redis_cache_duration_s":0.006591,"redis_cache_read_bytes":2816,"redis_cache_write_bytes":1035,"redis_shared_state_calls":1,"redis_shared_state_duration_s":0.000532,"redis_shared_state_read_bytes":181,"redis_shared_state_write_bytes":1335,"db_count":41,"db_write_count":0,"db_cached_count":10,"cpu_s":2.291446,"mem_objects":394125,"mem_bytes":52397272,"mem_mallocs":198648,"mem_total_bytes":68162272,"queue_duration_s":0.009214,"exception.class":"Rack::Timeout::RequestTimeoutException","exception.message":"Request ran for longer than 60000ms","exception.backtrace":["lib/gitlab/url_blocker.rb:113:in `getaddrinfo'","lib/gitlab/url_blocker.rb:113:in `get_address_info'","lib/gitlab/url_blocker.rb:48:in `validate!'","app/validators/addressable_url_validator.rb:83:in `validate_each'","app/models/badge.rb:43:in `build_rendered_url'","app/models/badge.rb:36:in `rendered_image_url'","app/models/badges/project_badge.rb:15:in `rendered_image_url'","app/views/projects/_home_panel.html.haml:93","app/views/projects/_home_panel.html.haml:89","app/views/projects/_home_panel.html.haml:87","app/views/projects/show.html.haml:14","app/controllers/application_controller.rb:128:in `render'","app/controllers/application_controller.rb:538:in `block in allow_gitaly_ref_name_caching'","lib/gitlab/gitaly_client.rb:341:in `allow_ref_name_caching'","app/controllers/application_controller.rb:537:in `allow_gitaly_ref_name_caching'","app/controllers/application_controller.rb:487:in `set_current_admin'","lib/gitlab/session.rb:11:in `with_session'","app/controllers/application_controller.rb:478:in `set_session_storage'","lib/gitlab/i18n.rb:99:in `with_locale'","lib/gitlab/i18n.rb:105:in `with_user_locale'","app/controllers/application_controller.rb:472:in `set_locale'","app/controllers/application_controller.rb:466:in `set_current_context'","lib/gitlab/metrics/elasticsearch_rack_middleware.rb:16:in `call'","lib/gitlab/middleware/rails_queue_duration.rb:33:in `call'","lib/gitlab/metrics/rack_middleware.rb:16:in `block in call'","lib/gitlab/metrics/web_transaction.rb:21:in `run'","lib/gitlab/metrics/rack_middleware.rb:16:in `call'","lib/gitlab/middleware/speedscope.rb:13:in `call'","lib/gitlab/request_profiler/middleware.rb:17:in `call'","lib/gitlab/jira/middleware.rb:19:in `call'","lib/gitlab/middleware/go.rb:20:in `call'","lib/gitlab/etag_caching/middleware.rb:21:in `call'","lib/gitlab/middleware/multipart.rb:172:in `call'","lib/gitlab/middleware/read_only/controller.rb:50:in `call'","lib/gitlab/middleware/read_only.rb:18:in `call'","lib/gitlab/middleware/same_site_cookies.rb:27:in `call'","lib/gitlab/middleware/handle_malformed_strings.rb:21:in `call'","lib/gitlab/middleware/basic_health_check.rb:25:in `call'","lib/gitlab/middleware/handle_ip_spoof_attack_error.rb:25:in `call'","lib/gitlab/middleware/request_context.rb:21:in `call'","config/initializers/fix_local_cache_middleware.rb:11:in `call'","lib/gitlab/middleware/rack_multipart_tempfile_factory.rb:19:in `call'","lib/gitlab/metrics/requests_rack_middleware.rb:74:in `call'","lib/gitlab/middleware/release_env.rb:12:in `call'"],"db_duration_s":0.23847,"view_duration_s":0.0,"duration_s":73.05203}

问题分析

经过 claude 的分析,发现是 badge 加载失败导致的

以下是完整回答:

根据这个 GitLab 日志,我可以看到问题的核心原因和解决方案:

问题分析

从日志中可以看到关键错误信息:

  1. 超时错误: Rack::Timeout::RequestTimeoutException (Request ran for longer than 60000ms) – 请求超过了60秒限制
  2. 根本原因: 错误发生在项目徽章(badge)渲染过程中,具体是在 lib/gitlab/url_blocker.rb:113:in 'getaddrinfo'
  3. 调用链: 项目页面渲染 → 徽章URL验证 → DNS解析超时

可能的原因

  1. 网络连通性问题: GitLab 尝试验证项目徽章的外部URL时,DNS解析或网络连接超时
  2. 徽章配置问题: 该项目配置了无效或无法访问的徽章URL
  3. 防火墙/代理问题: 网络策略阻止了对外部徽章服务的访问

解决方案

1. 临时解决方案 – 禁用徽章验证

方案无效。

2. 根本解决方案 – 检查项目徽章配置

  1. 通过管理员界面检查
    • 进入该项目的设置页面
    • 查看 “General” → “Badges” 部分
    • 删除或修复无效的徽章URL
  2. 通过数据库直接检查

    按照这个步骤成功解决。

    
    # 进入GitLab控制台
    gitlab-rails console

查找该项目的徽章

project = Project.find_by_full_path(‘xxx/xxx’) project.badges.each { |badge| puts “#{badge.id}: #{badge.link_url} | #{badge.image_url}” }

删除有问题的徽章

Badge.where(id: [有问题的徽章ID]).delete_all


### 3. 网络诊断

检查 GitLab 服务器的网络连通性:

```bash
# 测试DNS解析
nslookup [徽章URL的域名]

# 测试网络连通性
curl -I [完整的徽章URL]

4. 增加调试信息

临时启用详细日志来定位具体的URL:

# 在 /etc/gitlab/gitlab.rb 中
gitlab_rails['log_level'] = 'debug'

建议先尝试解决方案1作为紧急修复,然后通过解决方案2找到并修复具体的徽章配置问题。这样既能快速恢复服务,又能从根本上解决问题。

结论

没想到一个 badge 会导致这么大问题,可能因为版本比较低,不知道新版本有没有解决这个问题。

harbor Chartmuseum helm 图表缓存刷新

harbor 集成 Chartmuseum 实现 helm 图表的存储。

Chartmuseum 对于图表索引缓存的处理有问题,删除、重传 chart 不会刷新索引,需要手动刷新。

TL;DR

操作步骤如下:

  1. 停止 harbor,例如: docker compose stop
  2. 删除 /data/chart_storage/{project}/index-cache.yaml
  3. 删除 /data/redis/*
  4. 启动 harbor,例如: docker compose up -d

记得备份。

Refs