【RPC系列】4、自定义xml标签(用netty、zk手写RPC第一步)

自定义xml标签(用netty、zk手写RPC)

从XML认识XSD

废话不多说,xsd(xml schema defition)的作用如下
Xml Schema的用途:

  • 定义一个Xml文档中元素以及元素的属性
  • 定义某个节点的层级关系
  • 定义元素或者属性的数据类型以及默认值

直接上例子,下面这个就是一个自定义的xml标签结合了spring的标签完成的bean配置

<?xml version="1.0" encoding="UTF-8"?>
<beans 
//Spring的xsd标签的命名空间,也就是给xsd起了个别名,习惯性用http://....逼格高
xmlns="http://www.springframework.org/schema/beans"
	//xsi标签定义命名,这个基本用在自定义的xsd中使用原生的标签定义
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	//自定义rpc的xsd的命名空间,就是别名啦
	xmlns:rpc="http://rpc.kaer.com/schema/rpc"
	//这里就是别名——实际地址的映射,可以看到也是一群装逼的http://..但是后面多了个xsd的文件名,下面告诉你怎么找
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
	http://rpc.kaer.com/schema/rpc http://rpc.kaer.com/schema/rpc/rpc.xsd">
	<!-- zk配置,保存服务信息,用的就是自定义标签了rpc:表示用的是自定义rpc的xsd里面的标签 -->
	<rpc:server id="consumer_rpc" host="127.0.0.1"
		port="2181" />
	<!-- 服务订阅 -->
	<rpc:consumer id="consumer_helloService"
		api="com.kaer.rpc.demo.test.service.HelloService" alias="kaerRpc" />
	<!-- 服务注册 -->
	<rpc:provider id="provider_helloService"
		api="com.kaer.rpc.demo.test.service.HelloService" mapper="helloService"
		alias="kaerRpc" />
</beans>

首先我们要在Java工程的resources下面新建文件META-INF,在这个文件夹下面定义两个文件,分别是spring.handlers(配置了标签的解析类,就比如server这个标签应该怎么处理)和spring.schemas(别名与实际xsd文件路径的映射)
在这里插入图片描述
这里把rpc.xsd的定义也放在了一起,看一下两个文件的配置:
spring.handlers(其中“:”是需要转义符\的)

http://rpc.kaer.com/schema/rpc=com.kaer.rpc.demo.config.spring.MyNamespaceHandler

spring.schemas

http://rpc.kaer.com/schema/rpc/rpc.xsd=META-INF/rpc.xsd

下面一步步来,先看xsd是如何定义的

<?xml version="1.0"?>
<xsd:schema 
//表示数据类型等定义来自w3
xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
//表示文档中要定义的元素来自什么命名空间
targetNamespace="http://rpc.kaer.com/schema/rpc" 
//表示此文档的默认命名空间是什么
xmlns="http://rpc.kaer.com/schema/rpc"
//表示要求xml文档的每一个元素都要有命名空间指定
elementFormDefault="qualified" attributeFormDefault="unqualified"> 

	<!-- com.kaer.rpc.demo.config.ConsumerConfig -->
	<xsd:element name="consumer">
		<xsd:complexType>
			<xsd:complexContent>
				<xsd:extension base="beans:identifiedType">
					<xsd:attribute name="api" type="xsd:string">
						<xsd:annotation>
							<xsd:documentation><![CDATA[consumer]]></xsd:documentation>
						</xsd:annotation>
					</xsd:attribute>
					<xsd:attribute name="alias" type="xsd:string">
						<xsd:annotation>
							<xsd:documentation><![CDATA[consumer]]></xsd:documentation>
						</xsd:annotation>
					</xsd:attribute>
				</xsd:extension>
			</xsd:complexContent>
		</xsd:complexType>
	</xsd:element>
	
	<!-- com.kaer.rpc.demo.config.ProviderConfig -->
	<xsd:element name="provider">
		<xsd:complexType>
			<xsd:complexContent>
				<xsd:extension base="beans:identifiedType">
					<xsd:attribute name="api" type="xsd:string">
						<xsd:annotation>
							<xsd:documentation><![CDATA[provider]]></xsd:documentation>
						</xsd:annotation>
					</xsd:attribute>
					<xsd:attribute name="mapper" type="xsd:string">
						<xsd:annotation>
							<xsd:documentation><![CDATA[provider]]></xsd:documentation>
						</xsd:annotation>
					</xsd:attribute>
					<xsd:attribute name="alias" type="xsd:string">
						<xsd:annotation>
							<xsd:documentation><![CDATA[provider]]></xsd:documentation>
						</xsd:annotation>
					</xsd:attribute>
				</xsd:extension>
			</xsd:complexContent>
		</xsd:complexType>
	</xsd:element>
	
	<!-- com.kaer.rpc.demo.config.ServerConfig -->
	<xsd:element name="server">
		<xsd:complexType>
			<xsd:complexContent>
				<xsd:extension base="beans:identifiedType">
					<xsd:attribute name="host" type="xsd:string">
						<xsd:annotation>
							<xsd:documentation><![CDATA[server]]></xsd:documentation>
						</xsd:annotation>
					</xsd:attribute>
					<xsd:attribute name="port" type="xsd:integer">
						<xsd:annotation>
							<xsd:documentation><![CDATA[server]]></xsd:documentation>
						</xsd:annotation>
					</xsd:attribute>
				</xsd:extension>
			</xsd:complexContent>
		</xsd:complexType>
	</xsd:element>
</xsd:schema>

看一下MyNamespaceHandler的简单定义

public class MyNamespaceHandler extends NamespaceHandlerSupport {

	@Override
	public void init() {
		registerBeanDefinitionParser("consumer", new MyBeanDefinitionParser(ConsumerBean.class));
		registerBeanDefinitionParser("provider", new MyBeanDefinitionParser(ProviderBean.class));
		registerBeanDefinitionParser("server", new MyBeanDefinitionParser(ServerBean.class));
		
	}
}

以上就完成了从xsd到xml的定义配置。点击查看更多Xml Schema Definition
下一节将如果将服务注册到zk的节点上

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用Netty编写一个RPC框架可以分为以下几个步骤: 1. 定义通信协议:首先需要定义客户端和服务端之间的通信协议,包括消息的格式、编码方式、数据传输方式等。可以选择使用自定义协议或者现有的协议,如HTTP、TCP等。 2. 设计服务接口:定义服务接口,包括方法名、参数列表、返回值等。可以使用Java接口或者其他IDL(接口描述语言)工具来定义服务接口。 3. 实现服务端:使用Netty构建服务端,监听指定的端口,接收客户端的请求。当有请求到达时,根据协议解析请求数据,并根据请求调用相应的业务逻辑处理方法,最后将结果封装成响应数据发送给客户端。 4. 实现客户端:使用Netty构建客户端,连接到服务端的IP和端口。当需要调用远程服务时,根据协议封装请求数据,并发送给服务端。然后等待服务端返回响应数据,解析响应数据并返回给调用方。 5. 进行序列化和反序列化:在客户端和服务端之间进行数据传输时,需要对请求参数和响应结果进行序列化和反序列化。可以使用现有的序列化框架,如Protobuf、JSON等。 6. 管理连接和负载均衡:在实际应用中,可能存在多个服务提供者和多个消费者,需要管理客户端和服务端之间的连接,以及实现负载均衡策略,选择合适的服务提供者进行调用。 7. 异常处理和容错机制:在RPC框架中,需要考虑异常处理和容错机制。当服务端出现异常或不可用时,需要进行相应的处理,如重试、降级、熔断等。 这些步骤只是一个大致的框架,具体的实现细节和代码编写会根据具体需求而有所不同。通过以上步骤,你可以使用Netty构建一个简单的RPC框架。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值