通过Java SDK接入指南这篇文档,您已经了解了Java SDK导入、配置、解析IP、应用到网络库和接入验证的完整流程,本文主要介绍在Java客户端上使用阿里云OSS SDK接入HTTPDNS的具体方案。
1. 背景说明
阿里云对象存储OSS(Object Storage Service)是一款通用的云存储服务,可让开发者在各类应用中便捷地存储和访问用户头像、图片、音视频等文件。在Java端,可以通过集成OSS Java SDK来完成。
为了提升文件传输的稳定性和速度,可以将HTTPDNS SDK与OSS Java SDK进行结合,对OSS域名进行解析。这可以有效实现域名防劫持和DNS解析加速,从而优化应用访问OSS的网络体验。
2. 环境要求
Java 8 或以上
OSS Java SDK V2 (alibabacloud-oss-v2) 0.1.0-beta1 或以上
HTTPDNS Java SDK (alicloud-java-httpdns) 1.0.0 或以上
3. 基于 Apache HttpClient 实现 DnsResolver
OSS Java SDK V2 底层使用 Apache HttpClient,支持 4.x 和 5.x 两个版本。通过实现 DnsResolver 接口,可以将 HTTPDNS 集成到 OSS SDK 中。
HttpClient 5.x(默认)
import org.apache.hc.client5.http.DnsResolver;
import com.alibaba.sdk.java.httpdns.HttpDnsClient;
import com.alibaba.sdk.java.httpdns.HTTPDNSResult;
import com.alibaba.sdk.java.httpdns.RequestIpType;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
public class HttpDnsResolver implements DnsResolver {
@Override
public String resolveCanonicalHostname(String host) { return host; }
@Override
public InetAddress[] resolve(String host) throws UnknownHostException {
HTTPDNSResult result = HttpDnsClient.getClient("your-account-id")
.getHttpDnsResultForHostSyncNonBlocking(host, RequestIpType.both);
List<InetAddress> addresses = new ArrayList<>();
addAddresses(addresses, result != null ? result.getIps() : null);
addAddresses(addresses, result != null ? result.getIpv6s() : null);
return addresses.isEmpty() ? InetAddress.getAllByName(host) : addresses.toArray(new InetAddress[0]);
}
private void addAddresses(List<InetAddress> list, String[] ips) {
if (ips == null) return;
for (String ip : ips) {
try { list.add(InetAddress.getByName(ip)); } catch (UnknownHostException e) {}
}
}
}HttpClient 4.x
import org.apache.http.conn.DnsResolver;
import com.alibaba.sdk.java.httpdns.HttpDnsClient;
import com.alibaba.sdk.java.httpdns.HTTPDNSResult;
import com.alibaba.sdk.java.httpdns.RequestIpType;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
public class HttpDnsResolver4 implements DnsResolver {
@Override
public InetAddress[] resolve(String host) throws UnknownHostException {
HTTPDNSResult result = HttpDnsClient.getClient("your-account-id")
.getHttpDnsResultForHostSyncNonBlocking(host, RequestIpType.both);
List<InetAddress> addresses = new ArrayList<>();
addAddresses(addresses, result != null ? result.getIps() : null);
addAddresses(addresses, result != null ? result.getIpv6s() : null);
return addresses.isEmpty() ? InetAddress.getAllByName(host) : addresses.toArray(new InetAddress[0]);
}
private void addAddresses(List<InetAddress> list, String[] ips) {
if (ips == null) return;
for (String ip : ips) {
try { list.add(InetAddress.getByName(ip)); } catch (UnknownHostException e) {}
}
}
}4.x 和 5.x 的 DnsResolver 来自不同的包,5.x 需额外实现 resolveCanonicalHostname() 方法。
4. 接入OSS SDK
创建自定义 HttpClient 实例,并配置到 OSSClient 以替代默认 DNS 服务。
HttpClient 5.x(默认)
import com.alibaba.sdk.java.httpdns.HttpDnsClient;
import com.alibaba.sdk.java.httpdns.InitConfig;
import com.aliyun.sdk.service.oss2.OSSClient;
import com.aliyun.sdk.service.oss2.credentials.EnvironmentVariableCredentialsProvider;
import com.aliyun.sdk.service.oss2.transport.apache5client.Apache5HttpClient;
import com.aliyun.sdk.service.oss2.transport.apache5client.Apache5HttpClientBuilder;
// 初始化 HTTPDNS
InitConfig config = new InitConfig.Builder()
.setSecretKey("your-secret-key")
.setEnableHttps(true)
.setTimeoutMillis(2000)
.setEnableExpiredIp(true)
.enableMemoryCache(true)
.build();
HttpDnsClient.init("your-account-id", config);
// 创建 HttpClient 并注入 DnsResolver
Apache5HttpClient httpClient = Apache5HttpClientBuilder.create()
// ... 其他 HttpClient 配置
.dnsResolver(new HttpDnsResolver())
.build();
// 创建 OSSClient
OSSClient ossClient = OSSClient.newBuilder()
// ... 其他 OSS 配置
.httpClient(httpClient)
.build();HttpClient 4.x
// 初始化 HTTPDNS
InitConfig config = new InitConfig.Builder()
.setSecretKey("your-secret-key")
.setEnableHttps(true)
.setTimeoutMillis(2000)
.setEnableExpiredIp(true)
.enableMemoryCache(true)
.build();
HttpDnsClient.init("your-account-id", config);
// 创建 HttpClient 并注入 DnsResolver
Apache4HttpClient httpClient = Apache4HttpClientBuilder.create()
// ... 其他 HttpClient 配置
.dnsResolver(new HttpDnsResolver4())
.build();
// 创建 OSSClient 时注入 httpClient
OSSClient ossClient = OSSClient.newBuilder()
// ... 其他 OSS 配置
.useApacheHttpClient4(true) // 指定使用 HttpClient 4.x
.httpClient(httpClient)
.build();HTTPDNS SDK初始化设置需要在OSS SDK初始化设置之前完成。
5. 总结
通过将 HTTPDNS 与 OSS SDK 结合,可以有效防止 DNS 劫持并加速域名解析,提升访问的稳定性和安全性。实现的核心是为 OSS 配置一个带有 HTTPDNS 解析逻辑的自定义 HttpClient。
关键注意点:
自定义 HttpClient 后,需将超时、并发数等配置手动设置到 HttpClientBuilder 上,否则原配置会失效
需要先初始化 HTTPDNS,再初始化 OSS。并确保 OSS 域名已添加到 HTTPDNS 控制台的域名白名单中