Minimal settings.xml
1 | <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" |
aliyun
1 |
|
1 | <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" |
1 |
|
在很多场景下,需要将程序及依赖打包为单个 jar 包,方便部署、运行。打包成单体 jar 包,有多个插件可选,比如 maven-shade-plugin
、maven-assembly-plugin
。
以 gRPC 为例,我们有一个依赖包,里面自定义了 NameResolver。
1 | META-INF/services/io.grpc.NameResolverProvider |
如果我们恰巧引用了另外一个依赖包(jetcd-core),里面定义了其他的 NameResolver。
1 | META-INF/services/io.grpc.NameResolverProvider |
那么,在我们打包成单体 jar 时,将两个依赖包内的 META-INF/services/io.grpc.NameResolverProvider
合并为一个,这样打包后的程序在运行时才可以通过 SPI 机制,找到所有的扩展。
1 | 期望的打包后 META-INF/services/io.grpc.NameResolverProvider |
无论 maven-shade-plugin
还是 maven-assembly-plugin
,默认配置都不支持合并,需要单独配置。
对于 maven-shade-plugin
,需要添加 transformer。
1 | <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/> |
对于 maven-assembly-plugin
,需要添加组装描述文件 assembly.xml
,并启用 handler metaInf-services
。
1 | <!-- assembly.xml --> |
maven-shade-plugin
和 maven-assembly-plugin
配置,二选一。
1 | <plugin> |
1 | <plugin> |
assembly.xml
1 | <assembly xmlns="http://maven.apache.org/ASSEMBLY/2.1.0" |
./${filename}
」这样,不管是复制文件还是从剪切板复制图片,都会保存到文件同目录、同文件名下,引用的时候使用相对路径,这样,在上传到 git 仓库时,可以同步上传图片,并保持引用关系。
1 | localhost { |
1 | example.com { ... } # http 协议 |
原因是服务再返回请求设置 header 的 Location 字段时,没有把端口加进去,导致的现象是访问 http://doc.example.com:85
服务跳转到 http://doc.example.com/index
,由于端口丢失,导致无法访问。
从两个思路解决问题。
http://doc.example.com:85/index
)下面是 Caddy 的配置示例。
1 | header_down Location "^(http://doc.example.com)(.*)$" "$1:85$2" |
"^(http://doc.example.com)(.*)$"
, 匹配域名和 path"$1:85$2"
,在域名和 path 中间加端口下载插件 SwitchProxy,添加 charles 代理,并启用。
在 /etc/hosts
中添加 127.0.0.1 charles.prx
。
Map Remote
打开 iPhone 「设置 -> 无线局域网 -> 详情(已连接Wifi后的蓝色感叹号)-> 配置代理」,配置代理,ip 为开启 charles 的电脑 ip,port 为 charles 启动的代理端口,默认为 8888。
打开「Charles -> Help 」
会有如下提示。
在 safari 中访问网址 chls.pro/ssl
,允许下载证书,成功后会提示去设置中安装描述符。
打开「设置 -> 通用 -> 描述文件 -> Charles Proxy CA」,安装证书。
最后一步,启用证书。打开「设置 -> 通用 -> 关于手机 -> 证书信任设置 -> Charles Proxy CA」,启用它。
安装
使用清华开源站仓库安装参考这里。
1 | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" |
卸载
1 | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" |
1 | brew tap homebrew/cask-versions |
1 | openjdk |
管理多个版本 jdk 参考这里。
1 | 安装 jenv |
1 | { |
1 | { |
接口设计应以一些目标为导向,这些目标包含且不限于,易读、易懂、易用、清晰(意义明确,不易误用)、易维护、易扩展、功能强大且满足需求。要达到如上目标,在设计 API 时应考虑如下细节。
从形式来讲,API 不仅有 HTTP/WEB,还有 gRPC、Thrift。
对于思考设计良好的接口,可从下面两个视角着手。
Errors 是指客户端向服务发送错误数据,服务正确拒绝该数据。Errors 不会影响服务可用性。
Faults 是指服务对合法的请求无法正常返回结果。Faults 会影响服务可用性。
由于限流或配额失败(事先设定)引起的调用失败,不能算作 faults。如果是由于服务自我保护造成的请求失败,算作 faults,比如快速失败策略。
Latency 是指完成特定 API 调用消耗的时间,尽可能接近客户端计量。对于长操作请求,该指标记为初始请求耗时。
对于暴露长操作的服务,必须对这些指标跟踪 “Time to complete” 指标。
对于长操作,初始请求和检索请求都可能正常,但如果最终操作失败,必须汇总至总体的可用性指标中。
忽略服务端返回的多余字段。
忽略服务端返回数据字段的顺序。
URL 应该易读且易构造。
HTTP 1.1 RFC 7230 并未定义 URL 长度限制,如果服务接收到的请求 URL 长度大于其定义的限制长度,应返回 414 状态码。
所以,对于长度大于 2083 个字符的 URL ,应考虑服务是否可以接受。
方法 | 描述 | 是否幂等 |
---|---|---|
GET | 返回当前对象值 | 是 |
PUT | 替换或创建对象 | 是 |
DELETE | 删除对象 | 是 |
POST | 根据提供的数据创建新对象,或提交命令 | 否 |
HEAD | 为 GET 响应返回对象的元数据,资源支持 GET 请求,也应支持 HEAD 请求 | 是 |
PATCH | 对对象应用重要的更新 | 否 |
OPTIONS | 获取请求的信息 | 是 |
跟定 API 的基本操作,不能指定自定义 Headers。
返回值数据结构应分级,不应将业务数据放在第一级。
1 | # 异常 |
对于 code,应进行细致的划分,比如。
状态码 | 说明 | HTTP Status Code |
---|---|---|
0 | 请求正常返回 | 200 |
1000+ | 请求错误(参数、数据不存在等) | 400 |
2000+ | 元数据读取异常(不存在、格式异常) | 200 |
3000+ | 处理时异常 | 500 |
4000+ | 数据写入时异常 | 500 |
5000+ | 未知服务异常 | 500 |
对于 message 格式也应进行统一(避免英文/中文混用,有的 message 为英文,有的为中文),务必保证 code 不为 0 时返回有效 message。
有一些设计细节,很难判定那种方式实现比较好,这里做下讨论。
对于功能相似的多个接口,是使用一个接口 + 字段标识,还是拆分成多个接口。
1 | c 展示详细 COMMAND |
指定单个
1 | top -p <pid> # macos 使用 -pid 参数 |
指定多个
1 | top -p `pgrep -d ',' python3` # 非 macos |
1 | top -u wii # 只显示指定用户进程, macos 使用 -U 参数 |
1 | http_archive( |
1 | com_google_googleapis 包含了 common protos; 暂时保留 |