定时更换腾讯云CVM弹性公网IP
分类:腾讯云 别名:change-qcloud-cvm-elastic-public-ip-regularly

长时间以来自建的v2rayshadowrocket服务非常不稳定

常见症状是可以PING通,但无法使用

原先的方案是直接请求到日本服务器,socket返回信息,改造后变成了使用一台位于香港的腾讯云CVM作中转。因为流量只要出国了,流量怎么走都没有问题。

为了稳定使用/保持服务,就是要间隔性的更换腾讯云的服务器IP,它提供了弹性IP(VPC)的功能,如果在UI界面更换IP的话,非常麻烦,有解绑原IP,释放原IP,新增新IP,绑定新IP至CVM的这几个步骤。不过,腾讯云提供了API,所以我打算将一键更换IP的脚本,集成在我的网站后台,遇到封锁时一键更换IP即可。

以下是完成后的控制面板:

在开发时,本想一步到位,但发现在针对一个弹性IP进行操作后,需要等待一段时间才能进行下一步操作。例:解绑后不能立即释放、申请新IP后不能立即绑定

所以,流程为:
1、先解绑原IP(记录下EIP)
2、获取新IP(记录下EIP)
3、等待不低于10秒(分配需要时间)
4、释放原IP(需用到EIP)
5、将新IP绑定至CVM(需用到EIP)

接口1:

DescribeAddressesRequest getDescribeReq = DescribeAddressesRequest.fromJsonString("{}", DescribeAddressesRequest.class);
DescribeAddressesResponse getDescribeResp = vpcClient.DescribeAddresses(getDescribeReq);
Address address = null;
for (Address item : getDescribeResp.getAddressSet()) {
    if (item.getInstanceId().equals(qcloudConfig.getHkserviceid())) {
        address = item;
    }
}
JSONObject jsonObject = new JSONObject();

//解绑
DisassociateAddressRequest DisassociateReq = DisassociateAddressRequest.fromJsonString("{\"AddressId\":\"" + address.getAddressId() + "\"}", DisassociateAddressRequest.class);
vpcClient.DisassociateAddress(DisassociateReq);
jsonObject.put("oldAddressId", address.getAddressId());

//创建
AllocateAddressesRequest AllocateReq = AllocateAddressesRequest.fromJsonString("{\"AddressCount\":1,\"InternetChargeType\":\"TRAFFIC_POSTPAID_BY_HOUR\",\"InternetMaxBandwidthOut\":100}", AllocateAddressesRequest.class);
AllocateAddressesResponse AllocateResp = vpcClient.AllocateAddresses(AllocateReq);
jsonObject.put("newAddressId", AllocateResp.getAddressSet()[0]);
return GatewayUtil.get(true, 0, jsonObject);

接口2:

Map<String, Object> postMap = (Map<String, Object>) request.getAttribute("postMap");
if (postMap.get("oldAddressId") == null || postMap.get("newAddressId") == null) {
    return GatewayUtil.get(false, 100003, null);
}
String oldAddressId = postMap.get("oldAddressId").toString();
String newAddressId = postMap.get("newAddressId").toString();
//以上为本人自己的获取配置方法 请对照修改

//释放
ReleaseAddressesRequest releaseReq = ReleaseAddressesRequest.fromJsonString("{\"AddressIds\":[\"" + oldAddressId + "\"]}", ReleaseAddressesRequest.class);
vpcClient.ReleaseAddresses(releaseReq);

//绑定
AssociateAddressRequest AssociateReq = AssociateAddressRequest.fromJsonString("{\"AddressId\":\"" + newAddressId + "\",\"InstanceId\":\"" + qcloudConfig.getHkserviceid() + "\"}", AssociateAddressRequest.class);
vpcClient.AssociateAddress(AssociateReq);
关闭