Dubbo

Dubbo简介

Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。简单的说,dubbo就是个服务框架,如果没有分布式的需求,其实是不需要用的,只有在分布式的时候,才有dubbo这样的分布式服务框架的需求,并且本质上是个服务调用的东东,说白了就是个远程服务调用的分布式框架(告别Web Service模式中的WSdl,以服务者与消费者的方式在dubbo上注册)

 

Dubbo提供了三个关键功能:基于接口的远程调用,容错与负载均衡,服务自动注册与发现。

1.透明化的远程方法调用,就像调用本地方法一样调用远程方法,只需简单配置,没有任何API侵入。      
2.软负载均衡及容错机制,可在内网替代F5等硬件负载均衡器,降低成本,减少单点。
3. 服务自动注册与发现,不再需要写死服务提供方地址,注册中心基于接口名查询服务提供者的IP地址,并且能够平滑添加或删除服务提供者。

dubbo架构图如下所示

Provider: 暴露服务的服务提供方。
Consumer: 调用远程服务的服务消费方。
Registry: 服务注册与发现的注册中心。
Monitor: 统计服务的调用次调和调用时间的监控中心。
Container: 服务运行容器。

调用关系说明:
0 服务容器负责启动,加载,运行服务提供者。
1. 服务提供者在启动时,向注册中心注册自己提供的服务。
2. 服务消费者在启动时,向注册中心订阅自己所需的服务。
3. 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
4. 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
5. 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
 

 

Dubbo的使用

生产者

        <!--提供方应用信息,用于计算依赖关系 名字是什么无所谓:dubbo-admin后台显示的应用名-->
        <dubbo:application name="paycenter-server" logger="log4j" version="${dubbo.service.version}" organization="paycenter" environment="${dubbo.environment}"/>
	
        <!--用zookeeper作为注册中心 -->
	<dubbo:registry protocol="zookeeper" address="${dubbo.registry.address}" file="${catalina.home}/dubbo-registry/dubbo-registry.properties"/>
	
        <!--bubbo负载模式  loadbalance="roundrobin" -->
        <dubbo:provider protocol="dubbo" loadbalance="${dubbo.loadbalance}" />
	<!--<dubbo:monitor protocol="registry"/>-->

        <!--用dubbo的协议 在dubbo.protocol.accepts=20880/500端口暴露服务 
            下面会有修改协议暴露端口信息 -->
        <dubbo:protocol name="dubbo" accepts="${dubbo.protocol.accepts}"/>
	    <dubbo:protocol name="jsonrpc" server="jetty"/>

	<!--修改协议暴露端口信息 下面是配置文件中配置的暴露端口信息
	 	dubbo.ports=28005,28006,28007,28008
	 	dubbo.jsonrpc.ports=9995,9996,9997,9998-->
	<bean class="com.paycenter.dubbo.DynamicDubboPortReaderImpl" init-method="init">
		<property name="protocolName" value="dubbo"/>
		<property name="ports" value="${dubbo.ports}"/>
	</bean>
	<bean class="com.paycenter.dubbo.DynamicDubboPortReaderImpl" init-method="init">
		<property name="protocolName" value="jsonrpc"/>
		<property name="ports" value="${dubbo.jsonrpc.ports}"/>
	</bean>

        <!-- 声明需要暴露的服务接口
            retries="0"重试次数 写操作可以设置为0 避免重复调用SOA服务-->
        <dubbo:service protocol="dubbo,jsonrpc" interface="com.paycenter.api.service.IPayCenterFacade"
                   ref="payFacade" timeout="${dubbo.timeout}" retries="${dubbo.retries}"/>
public class DynamicDubboPortReaderImpl implements ApplicationContextAware {

	private ConfigurableApplicationContext applicationContext = null;

	private String protocolName;

	private String ports = null;

	/* 初始化方法 */

	public void init() {
		updateProtocolMessage(protocolName, getAddressPort());
	}

	public Integer getAddressPort() {
		if (ports == null) {
			return null;
		}
		for (String port : ports.split(",")) {
			Integer iport= Integer.valueOf(port);
			if(!isLoclePortUsing(iport)){
				return iport;
			}
		}
		return null;
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext)
			throws BeansException {
		this.applicationContext = (ConfigurableApplicationContext) applicationContext;
	}

	public void updateProtocolMessage(String protocolConfig, Integer port) {
		if (port != null) {
			// 判断初始化
			if (!applicationContext.containsBean(protocolConfig)) {
				System.out.println("没有【" + protocolConfig + "】协议");
			}
			// 获取协议
			ProtocolConfig protocolConfigSource = (ProtocolConfig) applicationContext.getBean(protocolConfig);
			// 修改协议暴露端口信息
			protocolConfigSource.setPort(port);
		}

	}

	/***
	 * true:already in using false:not using
	 */
	public static boolean isLoclePortUsing(int port) {
		boolean flag = true;
		try {
			flag = isPortUsing("127.0.0.1", port);
		} catch (Exception e) {
			flag = false;
		}
		return flag;
	}

	/***
	 * true:already in using false:not using
	 */
	public static boolean isPortUsing(String host, int port)throws UnknownHostException {
		boolean flag = false;
		InetAddress theAddress = InetAddress.getByName(host);
		Socket socket =null;
		try {
			socket = new Socket(theAddress, port);
			flag = true;
		} catch (IOException e) {
			flag = false;
		}finally{
			if(socket!=null){
				try {
					socket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return flag;
	}
	public String getPorts() {
		return ports;
	}
	public void setPorts(String ports) {
		this.ports = ports;
	}
	public String getProtocolName() {
		return protocolName;
	}
	public void setProtocolName(String protocolName) {
		this.protocolName = protocolName;
	}	
}

消费者

    <!--消费方应用名称,用于计算依赖关系 不是匹配条件,不要与提供方一样 -->
    <dubbo:application name="paycenter-web" logger="log4j" version="${dubbo.service.version}" organization="merchant" environment="${dubbo.environment}"/>
    <dubbo:registry protocol="zookeeper" address="${dubbo.registry.address}" file="${catalina.home}/dubbo-registry/dubbo-registry.properties"/>

    <!--生成远程服务代理
        id :是自己定义的(随便取)
        interface :一定要和服务提供方一致
        check="false"  检查级联依赖关系,默认为true,当有依赖服务的时候,需要根据需求进行设置-->
    <dubbo:reference id="payCenterFacade" protocol="dubbo" interface="com.paycenter.api.service.IPayCenterFacade"
                     timeout="${dubbo.timeout}" lazy="true" loadbalance="${dubbo.loadbalance}"
                     retries="${dubbo.retries}" check="false" mock=""/>
@Controller
public class QuickPaymentConfirmController extends BaseController {
    @Autowired
    private IPayCenterFacade payCenterFacade;

    @RequestMapping(value = "/quickPaymentConfirm", method = RequestMethod.POST)
    @ResponseBody
    public void quickPaymentConfirm(HttpServletRequest request) throws Exception {
        String jsonStr = getRequestString(request);
        //直接调用dubbo服务
        payCenterFacade.invoke(jsonStr,null);
    }
}

用原生API不集成Spring调用dubbo服务

    public static void main(String[] args) throws Exception {

		//创建应用
		ApplicationConfig ac = new ApplicationConfig();
		ac.setName("paycenter-server");

		//创建dubbo地址及接口
		ReferenceConfig<IPayCenterFacade> ref = new ReferenceConfig<IPayCenterFacade>();
		ref.setInterface(IPayCenterFacade.class);
		ref.setUrl("dubbo://192.168.23.1:28005/com.paycenter.api.service.IPayCenterFacade");
		ref.setApplication(ac);

		//创建dubbo方法
		MethodConfig mc = new MethodConfig();
		mc.setAsync(false);
		mc.setName("invoke");//方法名
		ref.setMethods(Arrays.asList(new MethodConfig[]{mc}));
		ref.setTimeout(10000);

		//创建方法的请求参数
		String requestJSON = "{\"biz_system\":5,\"goods_name\":\"测试商品爱国\",\"is_large_amount\":0,\"is_support_credit_card\":1,\"merchant_id\":\"020050210117\",\"notify_url\":\"http://www.baidu.com/\",\"order_no\":\"1540197454831\",\"order_time\":\"20181022163734\",\"pay_channel\":22,\"pay_money\":1,\"sign\":\"d6d80b3750d3f1b726690a2a61741955\",\"third_pay_platform\":\"59\"}";
		PaycenterCommunicationDTO commDto = new PaycenterCommunicationDTO();
		commDto.setMethod("getQRCode");

		//请求接口
		BaseResponse invoke = ref.get().invoke(requestJSON, commDto);
		System.out.println(invoke);
		System.out.println("ok");
	}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
单片微型计算机(MCU)经过多年的发展,在性能上有很大的进步,在型号上发展到上千种类,已经广泛应用于人类社会生活的各个领域。单片机课程已经成为高校计算机、自动化、测控以及电子信息工程等专业的重要课程。该课程是一门理论性和实践性都很强的课程,在实际教学中,应将理论教学和实验教学紧密结合。学生在掌握理论知识之余,必须通过编写程序、设计硬件电路、仿真、调试这一系列的实验过程,才能更好地掌握单片机的结构原理和应用技能。随着单片机及其接口技术的飞速发展,目前市场上供应的编程仿真实验资源并不能完全满足高校单片机课程教与学的需求,构建低成本、技术先进、源码公开的单片机编程仿真实验系统,对我国单片机课程的教学和单片机领域人才的培养具有重要的现实意义。 本论文结合目前教学中对单片机编程仿真实验系统的实际需求,采用模块化结构设计思想,精心设计和开发了单片机编程仿真实验系统。该单片机编程仿真实验系统由PC机端单片机编程控制软件和单片机编程仿真实验板两部分组成。PC机端的单片机编程控制软件可以自动检测到连接到单片机编程仿真实验板上的单片机,控制单片机编程器擦除、写入、读出、校验目标单片机ROM中的程序,以十六进制文件(.HEX文件)格式显示在控制界面内;单片机仿真实验系统能够把写入单片机的程序实时地运行,并呈现实际运行效果。单片机编程控制软件和单片机仿真实验板组成一个完整的单片机编程仿真实验系统。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值