stat相关知识
-
ajax statfunction ajax(opt) { opt = opt || {}; opt.method = opt.method.toUpperCase() || 'POST'; opt.url = opt.url || ''; //async:规定应当对请求进行异步(true)或同步(false)处理;true是在等待服务器响应时执行其他脚本,当响应就绪后对响应进行处理;false是等待服务器响应再执行 opt.async = opt.async || true; opt.data = opt.data || null; opt.success = opt.success || function () {}; var xmlHttp = null;
-
php5.4 安装出现问题在安装php5.4时出现下面的错误: 当make正常,但是使用make install出现错误:cp: cannot stat `sapi/cli/php.1': No such file or directory 解决的办法如下: make install fails -> cp: cannot stat sapi/cli/php.1: No such file So after doing some research I found the solution so just note to keep in mind if the same problem is encountered again. The fixt that worked was using the following commands: find . -name '
-
DOM解析XML 并保存数据结构package com.jiang.dom; import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; public class DOMTest { public stat
-
Linux文件时间通过stat命令可知,Linux文件和目录有3个时间属性,它们分别是:Access: 最后一次访问的时间Modify: 最后一次修改文件内容的时间Change: 最后一次修改文件属性(权限、大小、拥有者、内容)的时间验证步骤:1、新建一个新文件(> time)2、查看文件属性 (stat time || grep time) Access: 2017-09-26 19:28:01.441921854 +0800 Modify: 2017-09-26 19:28:01.441921854 +0800 Change: 2017-09-26 19:28:01.441921854 +0800 -rw-r--r--
stat相关课程
stat相关教程
- 5. 实例 1.统计/etc/fstab文件中每个单词出现的次数,并按从大到小排序awk '{for(i=1;i<=NF;i++){words[$i]++}}END{for(key in words)print key,words[key]}' /etc/fstab|sort -k2 -nrawk '{ips[$1]++}END{for(i in ips) print i,ips[i]}' access_nginx.log |column -t|sort -k2 -nr2.统计/etc/fstab每个文件系统类型出现的次数awk '!/^#/&&!/^$/{dev[$3]++}END{for(i in dev) print i,dev[i]}' /etc/fstab3.ping一个域名,输出ping此刻的时间ping baidu.com|awk '{print $0" "strftime("%Y-%m-%d %H:%M:%S")}'4.利用netstat监控服务是否正常监听netstat -lntup|awk 'NR>2{if($4 ~/.*:22/) print $0"yes";exit 0}'5.统计web服务器日志状态码awk '$9~"[0-9]"{stat[$9]++}END{for(i in stat) print i,stat[i]}' access_log
- 3. ZkClient API ZkClient 初始化 API// serverstring:服务器地址的字符串// 如:192.168.0.77:2181,192.168.0.88:2181,192.168.0.99:2181public ZkClient(String serverstring);// zkServers:服务器地址的字符串,connectionTimeout:连接超时时间,单位:mspublic ZkClient(String zkServers, int connectionTimeout);// sessionTimeout: session 超时时间public ZkClient(String zkServers, int sessionTimeout, int connectionTimeout);// ZkSerializer:序列化方式,实现类有:SerializableSerializer、BytesPushThroughSerializerpublic ZkClient(String zkServers, int sessionTimeout, int connectionTimeout, ZkSerializer zkSerializer);节点创建 API// path:节点全路径public void createPersistent(String path);// createParents:是否创建父节点public void createPersistent(String path, boolean createParents);// acl:权限列表public void createPersistent(String path, boolean createParents, List<ACL> acl);// data:节点数据public void createPersistent(String path, Object data);public void createPersistent(String path, Object data, List<ACL> acl);// 创建持久顺序节点public String createPersistentSequential(String path, Object data);public String createPersistentSequential(String path, Object data, List<ACL> acl);// 创建临时节点public void createEphemeral(String path);public void createEphemeral(String path, List<ACL> acl);// mode:节点类型public String create(String path, Object data, CreateMode mode);public String create(final String path, Object data, final List<ACL> acl, final CreateMode mode);public void createEphemeral(String path, Object data);public void createEphemeral(String path, Object data, List<ACL> acl);// 创建临时顺序节点public String createEphemeralSequential(String path, Object data);public String createEphemeralSequential(String path, Object data, List<ACL> acl);查询节点 API// 获取子节点列表public List<String> getChildren(String path);// watch:是否开启观察protected List<String> getChildren(final String path, final boolean watch);// 获取子节点数量public int countChildren(String path);// 节点是否存在protected boolean exists(final String path, final boolean watch);public boolean exists(String path);删除节点 APIpublic boolean delete(String path);// version:节点版本public boolean delete(final String path, final int version);读写节点数据 APIpublic <T> T readData(String path);public <T> T readData(String path, boolean returnNullIfPathNotExists);public <T> T readData(String path, Stat stat);protected <T> T readData(final String path, final Stat stat, final boolean watch);public void writeData(String path, Object object);public void writeData(String path, Object datat, int expectedVersion);观察节点 API// 观察节点的数据变化public void watchForData(final String path);// 观察子节点的变化public List<String> watchForChilds(final String path)
- 2.2 CuratorCacheListener CuratorCacheListener 是基于 CuratorCache 缓存实现的监听器,CuratorCache 对 ZooKeeper 事件监听进行了封装,能够自动处理反复注册监听。我们使用 CuratorCacheListener 时,需要使用构建器 CuratorCacheListenerBuilder 来对具体的事件监听进行构建,并且把 CuratorCacheListener 注册到 CuratorCache 缓存中。首先我们需要构建 CuratorCache 缓存实例,在 CuratorCache 接口中,build 为静态方法,我们可以直接调用:// 构建 CuratorCache 缓存实例static CuratorCache build(CuratorFramework client, String path, CuratorCache.Options... options) { return builder(client, path).withOptions(options).build();}我们来说明以下入参:CuratorFramework client 是 Curator 客户端;String path 是需要被监听的节点的路径;CuratorCache.Options... options 是对缓存设置的参数,我们可以设置以下 3 种:public static enum Options { // 单节点缓存 SINGLE_NODE_CACHE, // 对数据进行压缩 COMPRESSED_DATA, // CuratorCache 关闭后不清除缓存 DO_NOT_CLEAR_ON_CLOSE;}构建完缓存实例,我们再来构建 CuratorCacheListener ,在 CuratorCacheListener 接口中的构建方法 builder 为静态方法,我们可以直接调用:// builder 方法,返回 CuratorCacheListenerBuilder 构建器,我们就可以使用具体的监听方法了static CuratorCacheListenerBuilder builder() { return new CuratorCacheListenerBuilderImpl();}最后我们需要把 CuratorCacheListener 注册到 CuratorCache 中,并开启缓存:// 注册 CuratorCacheListener cache.listenable().addListener(listener);// 开启缓存cache.start();我们来看一个完整的例子:@Testvoid contextLoads() throws Exception { // 获取客户端 CuratorFramework client = curatorService.getCuratorClient(); // 开启会话 client.start(); // 构建 CuratorCache 实例 CuratorCache cache = CuratorCache.build(client, "/mooc"); // 使用 Fluent 风格和 lambda 表达式来构建 CuratorCacheListener 的事件监听 CuratorCacheListener listener = CuratorCacheListener.builder() // 开启对所有事件的监听 // type 事件类型:NODE_CREATED, NODE_CHANGED, NODE_DELETED; // oldNode 原节点:ChildData 类,包括节点路径,节点状态 Stat,节点 data // newNode 新节点:同上 .forAll((type, oldNode, newNode) -> { System.out.println("forAll 事件类型:" + type); System.out.println("forAll 原节点:" + oldNode); System.out.println("forAll 新节点:" + newNode); }) // 开启对节点创建事件的监听 .forCreates(childData -> { System.out.println("forCreates 新节点:" + childData); }) // 开启对节点更新事件的监听 .forChanges((oldNode, newNode) -> { System.out.println("forChanges 原节点:" + oldNode); System.out.println("forChanges 新节点:" + newNode); }) // 开启对节点删除事件的监听 .forDeletes(oldNode -> { System.out.println("forDeletes 原节点:" + oldNode); }) // 初始化 .forInitialized(() -> { System.out.println("forInitialized 初始化"); }) // 构建 .build(); // 注册 CuratorCacheListener 到 CuratorCache cache.listenable().addListener(listener); // CuratorCache 开启缓存 cache.start(); // mooc 节点创建 client.create().forPath("/mooc"); // mooc 节点更新 client.setData().forPath("/mooc","Wiki".getBytes()); // mooc 节点删除 client.delete().forPath("/mooc");}我们来查看 CuratorCacheListenerBuilder 接口中具体的事件监听,我们需要监听哪种事件就使用哪种方法:public interface CuratorCacheListenerBuilder { // 全部事件 CuratorCacheListenerBuilder forAll(CuratorCacheListener var1); // 创建事件 CuratorCacheListenerBuilder forCreates(Consumer<ChildData> var1); // 更新事件 CuratorCacheListenerBuilder forChanges(CuratorCacheListenerBuilder.ChangeListener var1); // 创建和更新事件 CuratorCacheListenerBuilder forCreatesAndChanges(CuratorCacheListenerBuilder.ChangeListener var1); // 删除事件 CuratorCacheListenerBuilder forDeletes(Consumer<ChildData> var1); // 初始化后开启线程异步执行 CuratorCacheListenerBuilder forInitialized(Runnable var1); // 子节点的事件 CuratorCacheListenerBuilder forPathChildrenCache(String var1, CuratorFramework var2, PathChildrenCacheListener var3); // 节点本身的事件和子节点的事件 CuratorCacheListenerBuilder forTreeCache(CuratorFramework var1, TreeCacheListener var2); // 节点本身的事件 CuratorCacheListenerBuilder forNodeCache(NodeCacheListener var1); // 初始化后开启监听 CuratorCacheListenerBuilder afterInitialized(); // 构建方法 CuratorCacheListener build(); /* * 更新事件时被调用 */ @FunctionalInterface public interface ChangeListener { void event(ChildData var1, ChildData var2); }}接下来我们执行测试方法,查看控制台输出:forInitialized 初始化forAll 事件类型:NODE_CREATEDforAll 原节点:nullforAll 新节点:ChildData{path='/mooc', stat=2760,2760,1598451457977,1598451457977,0,0,0,0,13,0,2760, data=[49, 57, 50, 46, 49, 54, 56, 46, 48, 46, 49, 48, 53]}forCreates 新节点:ChildData{path='/mooc', stat=2760,2760,1598451457977,1598451457977,0,0,0,0,13,0,2760, data=[49, 57, 50, 46, 49, 54, 56, 46, 48, 46, 49, 48, 53]}forAll 事件类型:NODE_CHANGEDforAll 原节点:ChildData{path='/mooc', stat=2760,2760,1598451457977,1598451457977,0,0,0,0,13,0,2760, data=[49, 57, 50, 46, 49, 54, 56, 46, 48, 46, 49, 48, 53]}forAll 新节点:ChildData{path='/mooc', stat=2760,2761,1598451457977,1598451457984,1,0,0,0,4,0,2760, data=[87, 105, 107, 105]}forChanges 原节点:ChildData{path='/mooc', stat=2760,2760,1598451457977,1598451457977,0,0,0,0,13,0,2760, data=[49, 57, 50, 46, 49, 54, 56, 46, 48, 46, 49, 48, 53]}forChanges 新节点:ChildData{path='/mooc', stat=2760,2761,1598451457977,1598451457984,1,0,0,0,4,0,2760, data=[87, 105, 107, 105]}forAll 事件类型:NODE_DELETEDforAll 原节点:ChildData{path='/mooc', stat=2760,2761,1598451457977,1598451457984,1,0,0,0,4,0,2760, data=[87, 105, 107, 105]}forAll 新节点:nullforDeletes 原节点:ChildData{path='/mooc', stat=2760,2761,1598451457977,1598451457984,1,0,0,0,4,0,2760, data=[87, 105, 107, 105]}我们发现,我们设置的 create,setData,delete 这 3 种事件都被监听到了,而且 forAll 每一种事件都监听到了,所以我们在使用的时候,选择我们需要的事件监听即可。介绍完 CuratorCacheListener 监听器,并完成了事件监听的测试,那么 Zookeeper 的 Watch 是如何运行的呢?接下来我们就来介绍 Watch 的运行原理。
- 3.1 临时节点和最小连接数策略实现负载均衡 首先我们需要在集群的每一个 Server 中都使用 Zookeeper 客户端 Curator 来连接 Zookeeper 服务端,当 Server 启动时,使用 Curator 连接 Zookeeper 服务端,并用自身的地址信息创建临时节点到 Zookeeper 服务端。我们还可以提供手动下线 Server 的方法,需要 Server 下线时可以手动调用删除节点的方法,需要 Server 上线时再次使用自身的地址信息来创建临时节点。除了维护 Server 的地址信息外,我们还需要维护请求的会话连接数,我们可以使用节点的 data 来保存请求会话的连接数。我们使用在 Zookeeper Curator 一节创建的 Spring Boot 测试项目来实现:/** * 最小连接数策略 Demo * Server 服务端注册地址 */@Componentpublic class MinimumConnectionsStrategyServer implements ApplicationRunner { @Autowired private CuratorService curatorService; // Curator 客户端 public CuratorFramework client; // 当前服务地址的临时节点 public static String SERVER_IP; // 当前服务地址临时节点的父节点,节点类型为持久节点 public static final String IMOOC_SERVER = "/imooc-server"; /** * 服务启动后自动执行 * * @param args args * @throws Exception Exception */ @Override public void run(ApplicationArguments args) throws Exception { // Curator 客户端开启会话 client = curatorService.getCuratorClient(); client.start(); // 注册地址信息到 Zookeeper registerAddressToZookeeper(); } /** * 注册地址信息到 Zookeeper * 服务启动时和服务手动上线时调用此方法 * * @throws Exception Exception */ public void registerAddressToZookeeper() throws Exception { // 判断父节点是否存在,不存在则创建持久节点 Stat stat = client.checkExists().forPath(IMOOC_SERVER); if (stat == null) { client.create().creatingParentsIfNeeded().forPath(IMOOC_SERVER); } // 获取本机地址 String address = InetAddress.getLocalHost().getHostAddress(); // 创建临时节点,节点路径为 /IMOOC_SERVER/address,节点 data 为 请求会话数,初始化时为 0. // /imooc-server/192.168.0.77 SERVER_IP = client.create() .withMode(CreateMode.EPHEMERAL) .forPath(IMOOC_SERVER + "/" + address, "0".getBytes()); } /** * 注销在 Zookeeper 上的注册的地址 * 服务手动下线时调用此方法 * * @throws Exception Exception */ public void deregistrationAddress() throws Exception { // 检查该节点是否存在 Stat stat = client.checkExists().forPath(SERVER_IP); // 存在则删除 if (stat != null) { client.delete().forPath(SERVER_IP); } }}在客户端的请求调用集群服务之前,先使用 Curator 获取 IMOOC_SERVER 下所有的临时节点,并寻找出 data 最小的临时节点,也就是最小连接数的服务。在客户端发送请求时,我们可以让当前 Server 的请求会话数加 1,并更新到临时节点的 data,完成请求时,我们可以让当前 Server 的请求会话数减 1,并更新到临时节点的 data 。/** * 最小连接数策略 Demo * Client 客户端发送请求 */@Componentpublic class MinimumConnectionsStrategyClient implements ApplicationRunner { @Autowired private CuratorService curatorService; // Curator 客户端 public CuratorFramework client; // 服务列表节点的 父节点 public static final String IMOOC_SERVER = "/imooc-server"; @Override public void run(ApplicationArguments args) throws Exception { // Curator 客户端开启会话 client = curatorService.getCuratorClient(); client.start(); } /** * 获取最小连接数的服务 * 发送请求前调用此方法,获取服务地址 * * @return String * @throws Exception Exception */ public String getTheMinimumNumberOfConnectionsService() throws Exception { // 获取所有子节点 List<String> list = client.getChildren().forPath(IMOOC_SERVER); // 新建 Map Map<String, Integer> map = new HashMap<>(); // 遍历服务列表,保存服务地址与请求会话数的映射关系 for (String s : list) { byte[] bytes = client.getData().forPath(IMOOC_SERVER + "/" + s); int i = Integer.parseInt(new String(bytes)); map.put(s, i); } // 寻找 map 中会话数最小的值 Optional<Map.Entry<String, Integer>> min = map.entrySet().stream().min(Map.Entry.comparingByValue()); // 不为空的话 if (min.isPresent()) { // 返回 服务地址 ip Map.Entry<String, Integer> entry = min.get(); return entry.getKey(); } else { // 没有则返回服务列表第一个服务地址 ip return list.get(0); } } /** * 增加该服务的请求会话数量 * 使用服务地址处理业务前调用此方法 * * @param ip 服务地址 * @throws Exception Exception */ public void increaseTheNumberOfRequestedSessions(String ip) throws Exception { byte[] bytes = client.getData().forPath(IMOOC_SERVER + "/" + ip); int i = Integer.parseInt(new String(bytes)); i++; client.setData().forPath(IMOOC_SERVER + "/" + ip, String.valueOf(i).getBytes()); } /** * 减少该服务的请求会话数量 * 请求结束时调用此方法减少会话数量 * * @param ip 服务地址 * @throws Exception Exception */ public void reduceTheNumberOfRequestedSessions(String ip) throws Exception { byte[] bytes = client.getData().forPath(IMOOC_SERVER + "/" + ip); int i = Integer.parseInt(new String(bytes)); i--; client.setData().forPath(IMOOC_SERVER + "/" + ip, String.valueOf(i).getBytes()); }}这样我们就使用 Zookeeper 的临时节点完成了一个简单的最小连接数策略的负载均衡。
- 3. Zookeeper 的四字监控命令 Zookeeper 的四字监控命令,每个命令都由 4 个字母组成,我们可以通过 telnet 或者 nc(netcat)向 Zookeeper 服务端发送命令,来获取 Zookeeper 的运行状态及相关信息。netcat 安装这里我们使用 netcat 进行演示,首先我们需要安装 netcat,使用 apt-get install 命令来安装 nc:# 安装 netcatsudo apt-get -y install netcat-traditional # 更新 nc 命令,使用 netcat-traditional 的 nc 命令sudo update-alternatives --config nc nc 安装完毕,接下来我们就可以使用 nc 来向 Zookeeper 服务端发送命令了。发送四字命令首先我们来查看 Zookeeper 服务端的运行状态:# 使用 nc 向 zookeeper 的地址和端口发送 stat 命令echo stat | nc 127.0.0.1 2181 # 输出 zookeeper 状态# Zookeeper 版本信息,构建时间Zookeeper version: 3.6.1--104dcb3e3fb464b30c5186d229e00af9f332524b, built on 04/21/2020 15:01 GMTClients: /127.0.0.1:44226[0](queued=0,recved=1,sent=0)# 延时信息Latency min/avg/max: 0/0.0/0# 收包Received: 3# 发包Sent: 2# 当前服务连接数Connections: 1# 堆积的未处理的请求数Outstanding: 0# 最大事务IDZxid: 0x2# 启动模式Mode: standalone# 节点数Node count: 5如果在发送命令时出现下面的情况:stat is not executed because it is not in the whitelist.说明我们的服务端未开启四字命令,需要我们在启动文件 zkServcie.sh 添加四字命令的支持。在 zkService.sh 文件中大约 77 行处添加 :ZOOMAIN="-Dzookeeper.4lw.commands.whitelist=* ${ZOOMAIN}"添加完毕后,使用 zkServcie.sh restart 命令重启 Zookeeper 服务端,再使用四字命令进行监控。接下来我们对 Zookeeper 的四字命令的含义,以及返回的信息进行介绍。
- 2.1 服务提供者 首先我们新建服务提供者项目,我们选择 Spring Initializr 来初始化 Spring Boot 项目,这是服务提供者的项目信息。pom.xml初始化完成,在 pom.xml 中加入项目所需的依赖。<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.4.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>cn.cdd</groupId> <artifactId>zookeeper-provider</artifactId> <version>0.0.1-SNAPSHOT</version> <name>zookeeper-provider</name> <description>zookeeper-providerDemo project for Spring Boot</description> <properties> <java.version>11</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- curator 客户端 --> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>5.1.0</version> </dependency> <!-- curator 客户端 --> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> <version>5.1.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build></project>依赖导入完成后,我们在 application.properties 配置文件中加入端口的配置。application.propertiesserver.port=8090接下来开始编写服务提供者的接口。ProviderService我们在 Spring Boot 主类的同级新建 service 目录,在 service 目录中新建 ProviderService 类。package cn.cdd.zookeeper.provider.service;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Service;import java.net.InetAddress;import java.net.UnknownHostException;@Servicepublic class ProviderService { @Value("${server.port}") private String port; public String callMethod(){ try { return "调用了服务提供者 " + InetAddress.getLocalHost().getHostAddress() + ":" + port + " 的方法"; } catch (UnknownHostException e) { e.printStackTrace(); } return null; }}接下来编写使用 Curator 连接 Zookeeper 服务的代码。CuratorService在 service 目录下新建 CuratorService 类:@Componentpublic class CuratorService implements ApplicationRunner { @Value("${server.port}") private String port; // CuratorFramework 客户端 private static CuratorFramework client; // 服务地址临时节点的父节点 private static final String PROVIDER_NODE = "/imooc/provider"; // 服务地址临时节点的全路径 private static String PROVIDER_ADDRESS; // 服务 ip private static String PROVIDER_IP; @Override public void run(ApplicationArguments args) throws Exception { // 获取客户端,连接 Zookeeper 服务 buildCuratorClient(); // 获取本机 IP PROVIDER_IP = InetAddress.getLocalHost().getHostAddress(); // 注册本机地址到 Zookeeper registeredAddress(); } /** * 构建 CuratorFramework 客户端,并开启会话 */ private void buildCuratorClient() { // 使用 CuratorFrameworkFactory 构建 CuratorFramework client = CuratorFrameworkFactory.builder() .sessionTimeoutMs(10000) // Zookeeper 地址 .connectString("127.0.0.1:2181") // 重连策略 .retryPolicy(new RetryForever(10000)) .build(); // 开启会话 client.start(); System.out.println(">>> 服务提供者连接 Zookeeper "); } /** * 注册服务地址 */ public String registeredAddress() { String address = null; try { Stat stat = client.checkExists().forPath(PROVIDER_NODE); if (stat == null) { client.create().creatingParentsIfNeeded().forPath(PROVIDER_NODE); } // 获取本机地址 address = PROVIDER_IP + ":" + port; // 创建临时节点 /imooc/provider/192.168.0.106:8090 PROVIDER_ADDRESS = client.create() .withMode(CreateMode.EPHEMERAL) .forPath(PROVIDER_NODE + "/" + address); } catch (Exception e) { e.printStackTrace(); } System.out.println(">>> 本服务已上线"); return ">>> 服务提供者 " + address + " 已上线"; } /** * 注销服务地址 */ public String deregistrationAddress() { String address = null; try { Stat stat = client.checkExists().forPath(PROVIDER_ADDRESS); if (stat != null) { client.delete().forPath(PROVIDER_ADDRESS); } // 获取本机地址 address = PROVIDER_IP + ":" + port; } catch (Exception e) { e.printStackTrace(); } System.out.println(">>> 本服务已下线"); return ">>> 服务提供者 " + address + " 已下线"; }}在 CuratorService 类中,我们提供了创建 Curator 客户端的方法,注册服务地址的方法以及注销服务地址的方法。在该服务启动时,就会自动连接 Zookeeper 服务,并且把自身的地址信息注册到 Zookeeper 的临时节点上。ProviderController这里我们使用 RESTful 的风格编写服务提供者对外的接口,在 service 目录同级创建 controller 目录,在 controller 中创建 ProviderController 。@RestController@RequestMapping("/provider")public class ProviderController { @Value("${server.port}") private String port; @Autowired private CuratorService curatorService; @Autowired private ProviderService providerService; /** * 调用方法 * http://localhost:8090/provider/callMethod * * @return String */ @GetMapping("/callMethod") public String callMethod() { return providerService.callMethod(); } /** * 上线服务 * http://localhost:8090/provider/online * * @return String */ @GetMapping("/online") public String registeredAddress() { return curatorService.registeredAddress(); } /** * 下线服务 * http://localhost:8090/provider/offline * * @return String */ @GetMapping("/offline") public String deregistrationAddress() { return curatorService.deregistrationAddress(); }}controller 编写完毕后,我们就可以对我们的服务提供者进行测试了。
stat相关搜索
-
s line
safari浏览器
samba
SAMP
samplerate
sandbox
sanitize
saper
sas
sass
save
smarty模板
smil
smtp
snapshot
snd
snmptrap
soap
soapclient
soap协议