Spring Cloud服务调用整合
远程过程调用(RPC)
一个计算机通信协议。该协议允许运行一台计算机的程序调用另一台计算机的子程序,而程序员无需额外地为这个交互作用编程。如果涉及的软件采用面向对象编程,那么远程过程调用亦可称作远程调用或远程方法调用
例如
- Java RMI(二进制协议)
- WebServices(文本协议)
- 消息传递
RPC是一种请求-响应协议,一次RPC在客户端初始化,再由客户端将请求消息请求消息传递到远程的服务器,执行指定的带有参数的过程。经过远程服务器执行过程后,将结果作为响应内容返回到客户端。 - 存根
再一次分布式计算机RPC中,客户端和服务器转化参数的一段代码。由于存根的参数化,RPC执行过程如同本地执行函数调用。存根必须在客户端和服务器两端均装载,并且保持兼容。
Spring Cloud Feign
因为在实际项目中,都是使用声明式调用服务。而不会在客服端和服务端存储2份相同的model和api定义。Feign在RestTemplate的基础上对其封装,由它来帮助我们定义和实现依赖服务接口的定义。Spring Cloud Feign 基于Netflix Feign 实现的,整理Spring Cloud Ribbon 与 Spring Cloud Hystrix,并且实现了声明式的Web服务客户端定义方式。
增加 spring-cloud-starter-feign 依赖
<!-- 添加 Spring Cloud Feign 依赖 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> </dependency>
2.申明 Feign 客户端
package com.segumentfault.spring.cloud.lesson10.api; import com.segumentfault.spring.cloud.lesson10.domain.User; import org.springframework.cloud.netflix.feign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import java.util.List; /** * 用户服务 * */ @FeignClient(name = "${user.service.name}") // 利用占位符避免未来整合硬编码 public interface UserService { /** * 保存用户 * * @param user * @return */ @PostMapping("/user/save") boolean saveUser(User user); /** * 查询所有的用户列表 * * @return non-null */ @GetMapping("/user/find/all") List<User> findAll(); }
注意,在使用@FeignClient name 属性尽量使用占位符,避免硬编码。否则,未来升级时,不得不升级客户端版本。
3.激活FeignClient
package com.segumentfault.spring.cloud.lesson10.user.service.client; import com.netflix.loadbalancer.IRule; import com.segumentfault.spring.cloud.lesson10.api.UserService; import com.segumentfault.spring.cloud.lesson10.user.service.client.rule.MyRule; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.cloud.netflix.feign.EnableFeignClients; import org.springframework.cloud.netflix.ribbon.RibbonClient; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate; /** * 引导类 * */ @SpringBootApplication @RibbonClient("user-service-provider") // 指定目标应用名称 @EnableCircuitBreaker // 使用服务短路 @EnableFeignClients(clients = UserService.class) // 申明 UserService 接口作为 Feign Client 调用 public class UserServiceClientApplication { public static void main(String[] args) { SpringApplication.run(UserServiceClientApplication.class, args); } /** * 将 {@link MyRule} 暴露成 {@link Bean} * * @return {@link MyRule} */ @Bean public IRule myRule() { return new MyRule(); } /** * 申明 具有负载均衡能力 {@link RestTemplate} * * @return */ @Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } }
Spring Cloud整合
整合负载均衡:Netflix Ribbon
客户端:激活@FeignClient UserService
package com.segumentfault.spring.cloud.lesson10.user.service.client; import com.netflix.loadbalancer.IRule; import com.segumentfault.spring.cloud.lesson10.api.UserService; import com.segumentfault.spring.cloud.lesson10.user.service.client.rule.MyRule; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.cloud.netflix.feign.EnableFeignClients; import org.springframework.cloud.netflix.ribbon.RibbonClient; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate; /** * 引导类 * */ @SpringBootApplication @RibbonClient("user-service-provider") // 指定目标应用名称 @EnableCircuitBreaker // 使用服务短路 @EnableFeignClients(clients = UserService.class) // 申明 UserService 接口作为 Feign Client 调用 public class UserServiceClientApplication { public static void main(String[] args) { SpringApplication.run(UserServiceClientApplication.class, args); } /** * 将 {@link MyRule} 暴露成 {@link Bean} * * @return {@link MyRule} */ @Bean public IRule myRule() { return new MyRule(); } /** * 申明 具有负载均衡能力 {@link RestTemplate} * * @return */ @Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } }
客户端:配置@FeignClient(name="${user.service.name}")中的占位符
调整application.properties
## 用户 Ribbon 客户端应用 spring.application.name = user-service-client ## 服务端口 server.port = 8080 ## 提供方服务名称 provider.service.name = user-service-provider ## 提供方服务主机 provider.service.host = localhost ## 提供方服务端口 provider.service.port = 9090 ## 关闭 Eureka Client,显示地通过配置方式注册 Ribbon 服务地址 eureka.client.enabled = false ## 定义 user-service-provider Ribbon 的服务器地址 ## 为 RibbonLoadBalancerClient 提供服务列表 user-service-provider.ribbon.listOfServers = \ http://${provider.service.host}:${provider.service.port} ## 扩展 IPing 实现 user-service-provider.ribbon.NFLoadBalancerPingClassName = \ com.segumentfault.spring.cloud.lesson10.user.service.client.ping.MyPing ## 配置 @FeignClient(name = "${user.service.name}") 中的占位符 ## user.service.name 实际需要制定 UserService 接口的提供方 ## 也就是 user-service-provider,可以使用 ${provider.service.name} 替代 user.service.name = ${provider.service.name}
服务端:实现UserService,即暴露HTTP REST服务
调整应用:user-service-provider
增加InMemoryUserService的Bean名称
package com.segumentfault.spring.cloud.lesson10.user.service.provider.service; import com.segumentfault.spring.cloud.lesson10.api.UserService; import com.segumentfault.spring.cloud.lesson10.domain.User; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * 内存实现{@link UserService} * */ @Service("inMemoryUserService") // Bean 名称 public class InMemoryUserService implements UserService { private Map<Long, User> repository = new ConcurrentHashMap<>(); @Override public boolean saveUser(User user) { return repository.put(user.getId(), user) == null; } @Override public List<User> findAll() { return new ArrayList(repository.values()); } }
UserSerrviceProviderController实现Feign客户端接口UserService
UserServiceProviderController.java
package com.segumentfault.spring.cloud.lesson10.user.service.web.controller; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty; import com.segumentfault.spring.cloud.lesson10.api.UserService; import com.segumentfault.spring.cloud.lesson10.domain.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Random; /** * 用户服务提供方 Controller * */ @RestController public class UserServiceProviderController implements UserService { @Autowired @Qualifier("inMemoryUserService") // 实现 Bean : InMemoryUserService private UserService userService; private final static Random random = new Random(); // 通过方法继承,URL 映射 :"/user/save" @Override public boolean saveUser(@RequestBody User user) { return userService.saveUser(user); } // 通过方法继承,URL 映射 :"/user/find/all" @Override public List<User> findAll() { return userService.findAll(); } /** * 获取所有用户列表 * * @return */ @HystrixCommand( commandProperties = { // Command 配置 // 设置操作时间为 100 毫秒 @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "100") }, fallbackMethod = "fallbackForGetUsers" // 设置 fallback 方法 ) @GetMapping("/user/list") public Collection<User> getUsers() throws InterruptedException { long executeTime = random.nextInt(200); // 通过休眠来模拟执行时间 System.out.println("Execute Time : " + executeTime + " ms"); Thread.sleep(executeTime); return userService.findAll(); } /** * {@link #getUsers()} 的 fallback 方法 * * @return 空集合 */ public Collection<User> fallbackForGetUsers() { return Collections.emptyList(); } }
客户端:使用UserService直接调用远程HTTP REST服务
package com.segumentfault.spring.cloud.lesson10.user.service.client.web.controller; import com.segumentfault.spring.cloud.lesson10.api.UserService; import com.segumentfault.spring.cloud.lesson10.domain.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import java.util.List; /** * {@link UserService} 客户端 {@link RestController} * * 注意:官方建议 客户端和服务端不要同时实现 Feign 接口 * 这里的代码只是一个说明,实际情况最好使用组合的方式,而不是继承 */ @RestController public class UserServiceClientController implements UserService { @Autowired private UserService userService; // 通过方法继承,URL 映射 :"/user/save" @Override public boolean saveUser(@RequestBody User user) { return userService.saveUser(user); } // 通过方法继承,URL 映射 :"/user/find/all" @Override public List<User> findAll() { return userService.findAll(); } }
整合服务短路:Netflix Hystrix
API:调整UserService并且实现Fallback
UserService Fallback实现
package com.segumentfault.spring.cloud.lesson10.fallback; import com.segumentfault.spring.cloud.lesson10.api.UserService; import com.segumentfault.spring.cloud.lesson10.domain.User; import java.util.Collections; import java.util.List; /** * {@link UserService} Fallback 实现 * */ public class UserServiceFallback implements UserService { @Override public boolean saveUser(User user) { return false; } @Override public List<User> findAll() { return Collections.emptyList(); } }
调整UserService @FeignClient fallback属性:
package com.segumentfault.spring.cloud.lesson10.api; import com.segumentfault.spring.cloud.lesson10.domain.User; import com.segumentfault.spring.cloud.lesson10.fallback.UserServiceFallback; import org.springframework.cloud.netflix.feign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import java.util.List; /** * 用户服务 * */ @FeignClient(name = "${user.service.name}",fallback = UserServiceFallback.class) // 利用占位符避免未来整合硬编码 public interface UserService { /** * 保存用户 * * @param user * @return */ @PostMapping("/user/save") boolean saveUser(User user); /** * 查询所有的用户列表 * * @return non-null */ @GetMapping("/user/find/all") List<User> findAll(); }
服务端:UserServiceProviderController#findAll()方法整合@HystrixCommand
package com.segumentfault.spring.cloud.lesson10.user.service.web.controller; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty; import com.segumentfault.spring.cloud.lesson10.api.UserService; import com.segumentfault.spring.cloud.lesson10.domain.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Random; /** * 用户服务提供方 Controller * */ @RestController public class UserServiceProviderController implements UserService { @Autowired @Qualifier("inMemoryUserService") // 实现 Bean : InMemoryUserService private UserService userService; private final static Random random = new Random(); // 通过方法继承,URL 映射 :"/user/save" @Override public boolean saveUser(@RequestBody User user) { return userService.saveUser(user); } @HystrixCommand( commandProperties = { // Command 配置 // 设置操作时间为 100 毫秒 @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "100") }, fallbackMethod = "fallbackForGetUsers" // 设置 fallback 方法 ) // 通过方法继承,URL 映射 :"/user/find/all" @Override public List<User> findAll() { return userService.findAll(); } /** * 获取所有用户列表 * * @return */ @HystrixCommand( commandProperties = { // Command 配置 // 设置操作时间为 100 毫秒 @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "100") }, fallbackMethod = "fallbackForGetUsers" // 设置 fallback 方法 ) @GetMapping("/user/list") public List<User> getUsers() throws InterruptedException { long executeTime = random.nextInt(200); // 通过休眠来模拟执行时间 System.out.println("Execute Time : " + executeTime + " ms"); Thread.sleep(executeTime); return userService.findAll(); } /** * {@link #getUsers()} 的 fallback 方法 * * @return 空集合 */ public List<User> fallbackForGetUsers() { return Collections.emptyList(); } }
整合服务发现:Netflix Eureka
创建 Eureka Server
pom.xml增加Eureka Server依赖
<dependencies> <!-- Eureka Server 依赖 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> </dependency> </dependencies>
创建引导类:EurekaServerApplication
package com.segumentfault.spring.cloud.lesson10.eureka.server; /** * Eureka Server 引导类 * */ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @SpringBootApplication @EnableEurekaServer public class EurekaServerApplication { public static void main(String[] args) { SpringApplication.run(EurekaServerApplication.class, args); } }
配置Eureka Server
application.properties
## Spring Cloud Eureka 服务器应用名称 spring.application.name = eureka-server ## Spring Cloud Eureka 服务器服务端口 server.port = 10000 ## 管理端口安全失效 management.security.enabled = false ## Spring Cloud Eureka 服务器作为注册中心 ## 通常情况下,不需要再注册到其他注册中心去 ## 同时,它也不需要获取客户端信息 ### 取消向注册中心注册 eureka.client.register-with-eureka = false ### 取消向注册中心获取注册信息(服务、实例信息) eureka.client.fetch-registry = false ## 解决 Peer / 集群 连接问题 eureka.instance.hostname = localhost eureka.client.serviceUrl.defaultZone = http://${eureka.instance.hostname}:${server.port}/eureka
端口信息
- user-service-client:8080
- user-service-provider:9090
- eureka-server:10000
客户端:配置服务发现客户端
配置应用:user-service-client
pom.xml增加eureka-client依赖
<!-- 依赖 Spring Cloud Netflix Eureka --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency>
激活服务发现客户端
UserServiceClientApplication.java
package com.segumentfault.spring.cloud.lesson10.user.service.client; import com.netflix.loadbalancer.IRule; import com.segumentfault.spring.cloud.lesson10.api.UserService; import com.segumentfault.spring.cloud.lesson10.user.service.client.rule.MyRule; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.cloud.netflix.feign.EnableFeignClients; import org.springframework.cloud.netflix.ribbon.RibbonClient; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate; /** * 引导类 * */ @SpringBootApplication @RibbonClient("user-service-provider") // 指定目标应用名称 @EnableCircuitBreaker // 使用服务短路 @EnableFeignClients(clients = UserService.class) // 申明 UserService 接口作为 Feign Client 调用 @EnableDiscoveryClient // 激活服务发现客户端 public class UserServiceClientApplication { public static void main(String[] args) { SpringApplication.run(UserServiceClientApplication.class, args); } /** * 将 {@link MyRule} 暴露成 {@link Bean} * * @return {@link MyRule} */ @Bean public IRule myRule() { return new MyRule(); } /** * 申明 具有负载均衡能力 {@link RestTemplate} * * @return */ @Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } }
配置Eureka注册中心
application.properties
## 用户 Ribbon 客户端应用 spring.application.name = user-service-client ## 服务端口 server.port = 8080 ## 提供方服务名称 provider.service.name = user-service-provider ## 提供方服务主机 provider.service.host = localhost ## 提供方服务端口 provider.service.port = 9090 ## 激活 Eureka Client eureka.client.enabled = true ## 扩展 IPing 实现 user-service-provider.ribbon.NFLoadBalancerPingClassName = \ com.segumentfault.spring.cloud.lesson10.user.service.client.ping.MyPing ## 配置 @FeignClient(name = "${user.service.name}") 中的占位符 ## user.service.name 实际需要制定 UserService 接口的提供方 ## 也就是 user-service-provider,可以使用 ${provider.service.name} 替代 user.service.name = ${provider.service.name} ## Spring Cloud Eureka 客户端 注册到 Eureka 服务器 eureka.client.serviceUrl.defaultZone = http://localhost:10000/eureka
服务端:配置服务发现客户端
配置应用:user-service-provider
pom.xml增加eureka-client依赖
<!-- 依赖 Spring Cloud Netflix Eureka --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency>
激活服务发现客户端UserServiceProviderApplication.java
package com.segumentfault.spring.cloud.lesson10.user.service; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.netflix.hystrix.EnableHystrix; /** * 引导类 * * @author <a href="mailto:mercyblitz@gmail.com">Mercy</a> * @since 0.0.1 */ @SpringBootApplication @EnableHystrix @EnableDiscoveryClient // 激活服务发现客户端 public class UserServiceProviderApplication { public static void main(String[] args) { SpringApplication.run(UserServiceProviderApplication.class, args); } }
配置Eureka注册中心
application.properties
## 用户服务提供方应用信息 spring.application.name = user-service-provider ## 服务端口 server.port = 9090 ## Spring Cloud Eureka 客户端 注册到 Eureka 服务器 eureka.client.serviceUrl.defaultZone = http://localhost:10000/eureka
整合配置服务器:Config Server
创建Config Server
pom.xml增加Config Server依赖
<dependencies> <!-- 依赖 Spring Cloud Config Server --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-server</artifactId> </dependency> </dependencies>
基于文件系统(File System)配置
注意:user-service-client application.properties 中以下内容将会被配置服务器中的 user-service.properties 替代.
创建
user-service.properties
## 提供方服务名称 provider.service.name = user-service-provider ## 提供方服务主机 provider.service.host = localhost ## 提供方服务端口 provider.service.port = 9090 ## 配置 @FeignClient(name = "${user.service.name}") 中的占位符 ## user.service.name 实际需要制定 UserService 接口的提供方 ## 也就是 user-service-provider,可以使用 ${provider.service.name} 替代 user.service.name = ${provider.service.name}
初始化配置文件根路径
cmd进入目标文件夹 然后git init
甚至配置文件根路径
application.properties
## Spring Cloud Config Server 应用名称 spring.application.name = config-server ## 服务器服务端口 server.port = 7070 ## 管理端口安全失效 management.security.enabled = false ## Spring Cloud Eureka 客户端 注册到 Eureka 服务器 eureka.client.serviceUrl.defaultZone = http://localhost:10000/eureka ## 配置服务器文件系统git 仓库 ## ${user.dir} 减少平台文件系统的不一致 ## 目前 ${user.dir}/config-server/src/main/resources/configs spring.cloud.config.server.git.uri = ${user.dir}/config-server/src/main/resources/configs
激活服务发现客户端
pom.xml
<!-- 依赖 Spring Cloud Netflix Eureka --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency>
application.properties
## Spring Cloud Eureka 客户端 注册到 Eureka 服务器 eureka.client.serviceUrl.defaultZone = http://localhost:10000/eureka
激活服务发现
package com.segumentfault.spring.cloud.lesson10.config.server; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.config.server.EnableConfigServer; /** * 配置服务器应用 * */ @EnableConfigServer @EnableDiscoveryClient @SpringBootApplication public class ConfigServerApplication { public static void main(String[] args) { SpringApplication.run(ConfigServerApplication.class, args); } }
创建并且配置bootstrap.properties
文件
bootstrap.properties
## 用户 Ribbon 客户端应用 spring.application.name = user-service-client ## 配置客户端应用关联的应用 ## spring.cloud.config.name 是可选的 ## 如果没有配置,采用 ${spring.application.name} spring.cloud.config.name = user-service ## 关联 profile spring.cloud.config.profile = default ## 关联 label spring.cloud.config.label = master ## 激活 Config Server 服务发现 spring.cloud.config.discovery.enabled = true ## Config Server 服务器应用名称 spring.cloud.config.discovery.serviceId = config-server ## Spring Cloud Eureka 客户端 注册到 Eureka 服务器 eureka.client.serviceUrl.defaultZone = http://localhost:10000/eureka
调整application.properties
## 服务端口 server.port = 8080 ## 扩展 IPing 实现 user-service-provider.ribbon.NFLoadBalancerPingClassName = \ com.segumentfault.spring.cloud.lesson10.user.service.client.ping.MyPing ## 以下内容有 Config Server 提供 ### 提供方服务名称 #provider.service.name = user-service-provider ### 提供方服务主机 #provider.service.host = localhost ### 提供方服务端口 #provider.service.port = 9090 ### 配置 @FeignClient(name = "${user.service.name}") 中的占位符 ### user.service.name 实际需要制定 UserService 接口的提供方 ### 也就是 user-service-provider,可以使用 ${provider.service.name} 替代 #user.service.name = ${provider.service.name}
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
visual studio code vue文件格式化插件
visual studio code安装插件eslint和vetur visual studio code文件setting.json文件配置 { "eslint.autoFixOnSave": true, "vetur.format.defaultFormatter.js": "vscode-typescript", "eslint.validate": [ "javascript", "javascriptreact", { "language": "vue", "autoFix": true } ] } 保存时,会格式化,执行格式化按钮,不会格式化
- 下一篇
python脚本实现ipv6的ddns功能
python脚本实现ipv6的ddns功能ipv6地址已经开始优先在三大运营商推广,我自己家用的就是联通宽带100M光纤入户。有一次,不经意间发现,我们的光猫竟然获取到了ipv6地址,于是我开始浮想联翩。 说干就干,我先是把光猫改成桥接模式,停止拨号,光猫的lan口连接华为路由器的wan口,再通过华为路由器拨号。 奇迹出现了,我们家的华为路由器包括华为路由器连接的局域网设备,竟然都获取到了ipv6地址。最可怕的是,每个设备都获取到了一个公网的ipv6地址。 虽然,这些设备获取到的ipv6地址,在哪都可以访问。但是,过1天问题又来了,这个ipv6地址竟然每天自动更新一次。 为了让我们家的设备,可以有永久不变的地址,于是我打起了aliyun 域名的主意,因为阿里云域名支持AAAA记录的解析,就是支持ipv6地址解析到域名。 我自己就花费一周时间,自己用python写出了一个ddns脚本,我已经放在了这里 https://gitlab.com/byygyy/ddns_ipv6.git 总体的思路就是,先调用ailiyun的域名接口,获得一个record id,再利用这个record id再持...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- Red5直播服务器,属于Java语言的直播服务器
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Docker安装Oracle12C,快速搭建Oracle学习环境
- CentOS6,CentOS7官方镜像安装Oracle11G
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- CentOS关闭SELinux安全模块
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16