Dubbo

- dubbo

参考大神的dubbo面试的18问https://blog.csdn.net/weixin_44337261/article/details/88149072

  1. dubbo是什么
    Dubbo是阿里巴巴SOA服务化治理方案的核心框架,Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。
  2. dubbo架构
    在这里插入图片描述
    1.当服务的提供者启动时,会将服务的名称:IP:端口会写入注册中心.
    2.注册中心内部会维护服务列表,某个服务提供者关机了,服务还能正常进行
    3.当消费者需要访问服务时,需要先访问注册中心获取服务列表信息.之后将服务列表保存到本地缓存中.方便后续的访问.在客户端内部有负载均衡的算法,筛选出一台服务器,之后进行访问.
    4.如果后台服务器出现宕机现象.这时注册中心通过心跳检测的方式判断服务器是否宕机.如果服务器宕机则会将该服务器信息从服务列表中删除.之后将新的服务列表发送消费者(客户端)进行更新.
  3. dubbo底层原理
    总结:RPC调用的规则可以传输java对象.底层实现时将数据转化流,并且该流经过加密处理.并且rpc内部使用UTF-8编码格式
    要求:传输的java对象必须序列化
    设计:
    在这里插入图片描述
    实现一个RPC远程调用框架

提供者:

public class ProviderMain {

	public static void main(String[] args) {
		try {
			System.out.println("start server 20881");
			ServerSocket serverSocket = new ServerSocket(20881);
			while (true) {
				ObjectInputStream objectInputStream = null;
				ObjectOutputStream objectOutputStream = null;
				try {
					Socket socket = serverSocket.accept();
					// 1,接收数据
					InputStream inputStream = socket.getInputStream();
					objectInputStream = new ObjectInputStream(inputStream);
					String interfaceName = objectInputStream.readUTF();
					String methodName = objectInputStream.readUTF();
					Class[] parameterTypes = (Class[]) objectInputStream.readObject();
					Object[] argments = (Object[]) objectInputStream.readObject();
					// 2,执行方法
					// 根据interfaceName找到实现类
					// map(interfaceName,impl);
					Class implClass = CartServiceImpl.class;
					Object implObject = implClass.newInstance();
					Method method = implClass.getMethod(methodName, parameterTypes);
					Object result = method.invoke(implObject, argments);

					// 3,返回数据
					OutputStream outputStream = socket.getOutputStream();
					objectOutputStream = new ObjectOutputStream(outputStream);
					objectOutputStream.writeObject(result);

				} catch (Exception e) {
					e.printStackTrace();
				} finally {
					objectInputStream.close();
					objectOutputStream.close();
				}

			}
		} catch (Exception e) {
			// TODO: handle exception
		}

	}

}

消费者:

public class CartController {

	public static void main(String[] args) {
		try {
			Object object = getObject(CartService.class);
			CartService cartService = (CartService) object;
			cartService.findCartByUserId(91L);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	static class MyInvocationHandler implements InvocationHandler {

		String interfaceName;

		public MyInvocationHandler(String interfaceName) {
			super();
			this.interfaceName = interfaceName;
		}

		public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
			ObjectOutputStream objectOutputStream = null;
			ObjectInputStream objectInputStream = null;
			try {
				// 1,得方法名,参数数据
				String methodName = method.getName();
				Class[] parameterTypes = method.getParameterTypes();

				// 2,发送数据
				Socket socket = new Socket("127.0.0.1", 20881);
				OutputStream outputStream = socket.getOutputStream();
				objectOutputStream = new ObjectOutputStream(outputStream);
				objectOutputStream.writeUTF(interfaceName);
				objectOutputStream.writeUTF(methodName);
				objectOutputStream.writeObject(parameterTypes);
				objectOutputStream.writeObject(args);
				// 3,接收数据
				InputStream inputStream = socket.getInputStream();
				objectInputStream = new ObjectInputStream(inputStream);
				Object result = objectInputStream.readObject();
				System.out.println("收到远程方法执行结果" + result);

				return result;
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				objectOutputStream.close();
				objectInputStream.close();
			}
			return null;
		}

	}

	public static Object getObject(final Class interfaceInfo) {
		// 1.将本地的接口调用转换成JDK的动态代理,在动态代理中实现接口的远程调用
		String interfaceName = interfaceInfo.getName();
		ClassLoader classLoader = interfaceInfo.getClassLoader();
		Class[] interfaces = { interfaceInfo };
		MyInvocationHandler myInvocationHandler = new MyInvocationHandler(interfaceName);
		Object object = Proxy.newProxyInstance(classLoader, interfaces, myInvocationHandler);
		return object;
	}

}
  1. 运用

提供者:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
	http://code.alibabatech.com/schema/dubbo 
	http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
	<!-- 1,设置应用名称 -->
	<dubbo:application name="provider-of-cart"/>
	<!-- 2,设置服务注册中心zookeeper地址 -->
	<dubbo:registry  address="zookeeper://192.168.216.202:2181">
	</dubbo:registry>
	<!-- 3,设置dubbo端口号 -->
	<dubbo:protocol name="dubbo" port="20883"></dubbo:protocol>
	<!-- 4,注册服务实现类对象-->
	<bean class="com.jt.service.CartServiceImpl" id="cartService">
	</bean>
	<!-- 5,设置客户端能访问接口,像servlet注册-->
	<dubbo:service interface="com.jt.service.CartService" ref="cartService">
	</dubbo:service>
</beans>

注册中心、dubbo端口、注册服务实现类、客户端服务访问接口

服务消费者:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
			http://www.springframework.org/schema/beans/spring-beans.xsd 
			http://code.alibabatech.com/schema/dubbo 
			http://code.alibabatech.com/schema/dubbo/dubbo.xsd ">
			
	<!--1,设置应用名-->
	<dubbo:application name="consumer-of-cart" />
	
	<!--2,设置注册中心地址 --> 
	<dubbo:registry address="zookeeper://192.168.216.202:2181" />
	
	
	<!--3,得到远程服务代理对象,可以像使用本地bean一样使用cartService -->
	<dubbo:reference timeout="50000"  id="cartService" interface="com.jt.cart.service.CartService" />

注册中心地址,访问接口名

  1. 面试问题
1、一般在项目中需要先启动服务提供者,后启动服务消费者,否则会报错,解决办法:
如:a,b 消费b ,  b也需要消费a中间的service.  
启动时检查提供者是否存在,true报错,false忽略 不检查

@Configuration
public class DubboConfig {

/**
 * 消费者配置不主动监督zookeeper服务
 *
 * @return
 */
@Bean
public ConsumerConfig consumerConfig() {
   ConsumerConfig consumerConfig = new ConsumerConfig();
   consumerConfig.setCheck(false);
   consumerConfig.setTimeout(40000);
   return consumerConfig;
}

}

   2、说明:当zk如果宕机后,消费者能否正确消息?????关zk,provider1,provider2
       答案:可以
	  因为zk会动态的向客户端更新服务列表信息.当zk宕机后,由于之前已经同步了zk的服务列表信息,所以客户端可以 按照自己已经缓存的清单进行访问.如果在这个期间服务端程序发现宕机现象,那么则访问故障机时由于不能通信,则等待超时时间,则访问下一台服务器.
如果这时,所有的服务端程序都宕机,则整个服务陷入瘫痪.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值