基于Dubbo框架构建分布式服务

一、Dubbo服务集群容错

   假设我们使用的是单机模式的Dubbo服务,如果在服务提供方(Provider)发布服务以后,服务消费方(Consumer)发出一次调用请求,恰好这次由于网络问题调用失败,那么我们可以配置服务消费方重试策略,可能消费方第二次重试调用是成功的(重试策略只需要配置即可,重试过程是透明的);但是,如果服务提供方发布服务所在的节点发生故障,那么消费方再怎么重试调用都是失败的,所以我们需要采用集群容错模式,这样如果单个服务节点因故障无法提供服务,还可以根据配置的集群容错模式,调用其他可用的服务节点,这就提高了服务的可用性。

  首先,根据Dubbo文档,我们引用文档提供的一个架构图以及各组件关系说明,如下所示:

    上述各个组件之间的关系(引自Dubbo文档)说明如下:

  • 这里的Invoker是Provider的一个可调用Service的抽象,Invoker封装了Provider地址及Service接口信息。
  • Directory代表多个Invoker,可以把它看成List,但与List不同的是,它的值可能是动态变化的,比如注册中心推送变更。
  • Cluster将Directory中的多个Invoker伪装成一个Invoker,对上层透明,伪装过程包含了容错逻辑,调用失败后,重试另一个。
  • Router负责从多个Invoker中按路由规则选出子集,比如读写分离,应用隔离等。
  • LoadBalance负责从多个Invoker中选出具体的一个用于本次调用,选的过程包含了负载均衡算法,调用失败后,需要重选。

    我们也简单说明目前Dubbo支持的集群容错模式,每种模式适应特定的应用场景,可以根据实际需要进行选择。Dubbo内置支持如下6种集群模式:

  • Failover Cluster模式

     配置值为failover。这种模式是Dubbo集群容错默认的模式选择,调用失败时,会自动切换,重新尝试调用其他节点上可用的服务。对于一些幂等性操作可以使用该模式,如读操作,因为每次调用的副作用是相同的,所以可以选择自动切换并重试调用,对调用者完全透明。可以看到,如果重试调用必然会带来响应端的延迟,如果出现大量的重试调用,可能说明我们的服务提供方发布的服务有问题,如网络延迟严重、硬件设备需要升级、程序算法非常耗时,等等,这就需要仔细检测排查了。
例如,可以这样显式指定Failover模式,或者不配置则默认开启Failover模式,配置示例如下:

<dubbo:service interface="org.shirdrn.dubbo.api.ChatRoomOnlineUserCounterService" version="1.0.0"cluster="failover" retries="2" timeout="100" ref="chatRoomOnlineUserCounterService" protocol="dubbo" ><dubbo:method name="queryRoomUserCount" timeout="80" retries="2" />
</dubbo:service>

 上述配置使用Failover Cluster模式,如果调用失败一次,可以再次重试2次调用,服务级别调用超时时间为100ms,调用方法queryRoomUserCount的超时时间为80ms,允许重试2次,最坏情况调用花费时间160ms。如果该服务接口org.shirdrn.dubbo.api.ChatRoomOnlineUserCounterService还有其他的方法可供调用,则其他方法没有显式配置则会继承使用dubbo:service配置的属性值。

  • Failfast Cluster模式:配置值为failfast。这种模式称为快速失败模式,调用只执行一次,失败则立即报错。这种模式适用于非幂等性操作,每次调用的副作用是不同的,如写操作,比如交易系统我们要下订单,如果一次失败就应该让它失败,通常由服务消费方控制是否重新发起下订单操作请求(另一个新的订单)。
  • Failsafe Cluster模式:配置值为failsafe。失败安全模式,如果调用失败, 则直接忽略失败的调用,而是要记录下失败的调用到日志文件,以便后续审计。
  • Failback Cluster模式:配置值为failback。失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作。
  • Forking Cluster模式:配置值为forking。并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。
  • Broadcast Cluster模式:配置值为broadcast。广播调用所有提供者,逐个调用,任意一台报错则报错(2.1.0开始支持)。通常用于通知所有提供者更新缓存或日志等本地资源信息。

   上面的6种模式都可以应用于生产环境,我们可以根据实际应用场景选择合适的集群容错模式。如果我们觉得Dubbo内置提供的几种集群容错模式都不能满足应用需要,也可以定制实现自己的集群容错模式,因为Dubbo框架给我提供的扩展的接口,只需要实现接口com.alibaba.dubbo.rpc.cluster.Cluster即可,接口定义如下所示:

@SPI(FailoverCluster.NAME)
public interface Cluster {/*** Merge the directory invokers to a virtual invoker.* @param <T>* @param directory* @return cluster invoker* @throws RpcException*/@Adaptive<T> Invoker<T> join(Directory<T> directory) throws RpcException;}

  关于如何实现一个自定义的集群容错模式,可以参考Dubbo源码中内置支持的汲取你容错模式的实现,6种模式对应的实现类如下所示:

com.alibaba.dubbo.rpc.cluster.support.FailoverCluster
com.alibaba.dubbo.rpc.cluster.support.FailfastCluster
com.alibaba.dubbo.rpc.cluster.support.FailsafeCluster
com.alibaba.dubbo.rpc.cluster.support.FailbackCluster
com.alibaba.dubbo.rpc.cluster.support.ForkingCluster
com.alibaba.dubbo.rpc.cluster.support.AvailableCluster

 可能我们初次接触Dubbo时,不知道如何在实际开发过程中使用Dubbo的集群模式,后面我们会以Failover Cluster模式为例开发我们的分布式应用,再进行详细的介绍。

二、Dubbo服务负载均衡

  Dubbo框架内置提供负载均衡的功能以及扩展接口,我们可以透明地扩展一个服务或服务集群,根据需要非常容易地增加/移除节点,提高服务的可伸缩性。Dubbo框架内置提供了4种负载均衡策略,如下所示:

  • Random LoadBalance:随机策略,配置值为random。可以设置权重,有利于充分利用服务器的资源,高配的可以设置权重大一些,低配的可以稍微小一些
  • RoundRobin LoadBalance:轮询策略,配置值为roundrobin。
  • LeastActive LoadBalance:配置值为leastactive。根据请求调用的次数计数,处理请求更慢的节点会受到更少的请求
  • ConsistentHash LoadBalance:一致性Hash策略,具体配置方法可以参考Dubbo文档。相同调用参数的请求会发送到同一个服务提供方节点上,如果某个节点发生故障无法提供服务,则会基于一致性Hash算法映射到虚拟节点上(其他服务提供方)

   在实际使用中,只需要选择合适的负载均衡策略值,配置即可,下面是上述四种负载均衡策略配置的示例:

<dubbo:service interface="org.shirdrn.dubbo.api.ChatRoomOnlineUserCounterService" version="1.0.0"cluster="failover" retries="2" timeout="100" loadbalance="random"ref="chatRoomOnlineUserCounterService" protocol="dubbo" ><dubbo:method name="queryRoomUserCount" timeout="80" retries="2" loadbalance="leastactive" />
</dubbo:service>

   上述配置,也体现了Dubbo配置的继承性特点,也就是dubbo:service元素配置了loadbalance=”random”,则该元素的子元素dubbo:method如果没有指定负载均衡策略,则默认为loadbalance=”random”,否则如果dubbo:method指定了loadbalance=”leastactive”,则使用子元素配置的负载均衡策略覆盖了父元素指定的策略(这里调用queryRoomUserCount方法使用leastactive负载均衡策略)。
   当然,Dubbo框架也提供了实现自定义负载均衡策略的接口,可以实现com.alibaba.dubbo.rpc.cluster.LoadBalance接口,接口定义如下所示:

/**
* LoadBalance. (SPI, Singleton, ThreadSafe)
*
* <a href="http://en.wikipedia.org/wiki/Load_balancing_(computing)">Load-Balancing</a>
*/
@SPI(RandomLoadBalance.NAME)
public interface LoadBalance {/*** select one invoker in list.* @param invokers invokers.* @param url refer url* @param invocation invocation.* @return selected invoker.*/@Adaptive("loadbalance")<T> Invoker<T> select(List<Invoker<T>> invokers, URL url, Invocation invocation) throws RpcException;}

 如何实现一个自定义负载均衡策略,可以参考Dubbo框架内置的实现,如下所示的3个实现类:

com.alibaba.dubbo.rpc.cluster.loadbalance.RandomLoadBalance
com.alibaba.dubbo.rpc.cluster.loadbalance.RoundRobinLoadBalance
com.alibaba.dubbo.rpc.cluster.loadbalance.LeastActiveLoadBalance

三、Dubbo服务集群容错实践

   手机应用是以聊天室为基础的,我们需要收集用户的操作行为,然后计算聊天室中在线人数,并实时在手机应用端显示人数,整个系统的架构如图所示:

 

    上图中,主要包括了两大主要流程:日志收集并实时处理流程调用读取实时计算结果流程,我们使用基于Dubbo框架开发的服务来提供实时计算结果读取聊天人数的功能。上图中,实际上业务接口服务器集群也可以基于Dubbo框架构建服务,就看我们想要构建什么样的系统来满足我们的需要。
如果不使用注册中心,服务消费方也能够直接调用服务提供方发布的服务,这样需要服务提供方将服务地址暴露给服务消费方,而且也无法使用监控中心的功能,这种方式成为直连。
    如果我们使用注册中心,服务提供方将服务发布到注册中心,而服务消费方可以通过注册中心订阅服务,接收服务提供方服务变更通知,这种方式可以隐藏服务提供方的细节,包括服务器地址等敏感信息,而服务消费方只能通过注册中心来获取到已注册的提供方服务,而不能直接跨过注册中心与服务提供方直接连接。这种方式的好处是还可以使用监控中心服务,能够对服务的调用情况进行监控分析,还能使用Dubbo服务管理中心,方便管理服务,我们在这里使用的是这种方式,也推荐使用这种方式。使用注册中心的Dubbo分布式服务相关组件结构,如下图所示:

   下面,开发部署我们的应用,通过如下4个步骤来完成:

  • 服务接口定义

     服务接口将服务提供方(Provider)和服务消费方(Consumer)连接起来,服务提供方实现接口中定义的服务,即给出服务的实现,而服务消费方负责调用服务。我们接口中给出了2个方法,一个是实时查询获取当前聊天室内人数,另一个是查询一天中某个/某些聊天室中在线人数峰值,接口定义如下所示: 

package org.shirdrn.dubbo.api;import java.util.List;public interface ChatRoomOnlineUserCounterService {String queryRoomUserCount(String rooms);List<String> getMaxOnlineUserCount(List<String> rooms, String date, String dateFormat);
}

  接口是服务提供方和服务消费方公共遵守的协议,一般情况下是服务提供方将接口定义好后提供给服务消费方。

  • 服务提供方

    服务提供方实现接口中定义的服务,其实现和普通的服务没什么区别,我们的实现类为ChatRoomOnlineUserCounterServiceImpl,代码如下所示:

package org.shirdrn.dubbo.provider.service;import java.util.List;import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.shirdrn.dubbo.api.ChatRoomOnlineUserCounterService;
import org.shirdrn.dubbo.common.utils.DateTimeUtils;import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import com.alibaba.dubbo.common.utils.StringUtils;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;public class ChatRoomOnlineUserCounterServiceImpl implements ChatRoomOnlineUserCounterService {private static final Log LOG = LogFactory.getLog(ChatRoomOnlineUserCounterServiceImpl.class);private JedisPool jedisPool;private static final String KEY_USER_COUNT = "chat::room::play::user::cnt";private static final String KEY_MAX_USER_COUNT_PREFIX = "chat::room::max::user::cnt::";private static final String DF_YYYYMMDD = "yyyyMMdd";public String queryRoomUserCount(String rooms) {LOG.info("Params[Server|Recv|REQ] rooms=" + rooms);StringBuffer builder = new StringBuffer();if(!Strings.isNullOrEmpty(rooms)) {Jedis jedis = null;try {jedis = jedisPool.getResource();String[] fields = rooms.split(",");List<String> results = jedis.hmget(KEY_USER_COUNT, fields);builder.append(StringUtils.join(results, ","));} catch (Exception e) {LOG.error("", e);} finally {if(jedis != null) {jedis.close();}}}LOG.info("Result[Server|Recv|RES] " + builder.toString());return builder.toString();}@Overridepublic List<String> getMaxOnlineUserCount(List<String> rooms, String date, String dateFormat) {// HGETALL chat::room::max::user::cnt::20150326LOG.info("Params[Server|Recv|REQ] rooms=" + rooms + ",date=" + date + ",dateFormat=" + dateFormat);String whichDate = DateTimeUtils.format(date, dateFormat, DF_YYYYMMDD);String key = KEY_MAX_USER_COUNT_PREFIX + whichDate;StringBuffer builder = new StringBuffer();if(rooms != null && !rooms.isEmpty()) {Jedis jedis = null;try {jedis = jedisPool.getResource();return jedis.hmget(key, rooms.toArray(new String[rooms.size()]));} catch (Exception e) {LOG.error("", e);} finally {if(jedis != null) {jedis.close();}}}LOG.info("Result[Server|Recv|RES] " + builder.toString());return Lists.newArrayList();}public void setJedisPool(JedisPool jedisPool) {this.jedisPool = jedisPool;}}

   代码中通过读取Redis中数据来完成调用,逻辑比较简单。对应的Maven POM依赖配置,如下所示:

<dependencies><dependency><groupId>org.shirdrn.dubbo</groupId><artifactId>dubbo-api</artifactId><version>0.0.1-SNAPSHOT</version></dependency><dependency><groupId>org.shirdrn.dubbo</groupId><artifactId>dubbo-commons</artifactId><version>0.0.1-SNAPSHOT</version></dependency><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>2.5.2</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId><version>2.2</version></dependency><dependency><groupId>org.jboss.netty</groupId><artifactId>netty</artifactId><version>3.2.7.Final</version></dependency>
</dependencies>

   有关对Dubbo框架的一些依赖,我们单独放到一个通用的Maven Module中(详见后面“附录:Dubbo使用Maven构建依赖配置”),这里不再多说。服务提供方实现,最关键的就是服务的配置,因为Dubbo基于Spring来管理配置和实例,所以通过配置可以指定服务是否是分布式服务,以及通过配置增加很多其它特性。我们的配置文件为provider-cluster.xml,内容如下所示:

<?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"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"><bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"><property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" /><property name="ignoreResourceNotFound" value="true" /><property name="locations"><list><value>classpath*:jedis.properties</value></list></property></bean><dubbo:application name="chatroom-cluster-provider" /><dubbo:registry address="zookeeper://zk1:2181?backup=zk2:2181,zk3:2181" /><dubbo:protocol name="dubbo" port="20880" /><dubbo:service interface="org.shirdrn.dubbo.api.ChatRoomOnlineUserCounterService" version="1.0.0"cluster="failover" retries="2" timeout="1000" loadbalance="random" actives="100" executes="200"ref="chatRoomOnlineUserCounterService" protocol="dubbo" ><dubbo:method name="queryRoomUserCount" timeout="500" retries="2" loadbalance="roundrobin" actives="50" /></dubbo:service><bean id="chatRoomOnlineUserCounterService" class="org.shirdrn.dubbo.provider.service.ChatRoomOnlineUserCounterServiceImpl" ><property name="jedisPool" ref="jedisPool" /></bean><bean id="jedisPool" class="redis.clients.jedis.JedisPool" destroy-method="destroy"><constructor-arg index="0"><bean class="org.apache.commons.pool2.impl.GenericObjectPoolConfig"><property name="maxTotal" value="${redis.pool.maxTotal}" /><property name="maxIdle" value="${redis.pool.maxIdle}" /><property name="minIdle" value="${redis.pool.minIdle}" /><property name="maxWaitMillis" value="${redis.pool.maxWaitMillis}" /><property name="testOnBorrow" value="${redis.pool.testOnBorrow}" /><property name="testOnReturn" value="${redis.pool.testOnReturn}" /><property name="testWhileIdle" value="true" /></bean></constructor-arg><constructor-arg index="1" value="${redis.host}" /><constructor-arg index="2" value="${redis.port}" /><constructor-arg index="3" value="${redis.timeout}" /></bean></beans>

 上面配置中,使用dubbo协议,集群容错模式为failover,服务级别负载均衡策略为random,方法级别负载均衡策略为roundrobin(它覆盖了服务级别的配置内容),其他一些配置内容可以参考Dubbo文档。我们这里是从Redis读取数据,所以使用了Redis连接池。
启动服务示例代码如下所示:

package org.shirdrn.dubbo.provider;import org.shirdrn.dubbo.provider.common.DubboServer;public class ChatRoomClusterServer {public static void main(String[] args) throws Exception {DubboServer.startServer("classpath:provider-cluster.xml");}}

 上面调用了DubboServer类的静态方法startServer,如下所示:

public static void startServer(String config) {ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(config);try {context.start();System.in.read();} catch (IOException e) {e.printStackTrace();} finally {context.close();}
}

 方法中主要是初始化Spring IoC容器,全部对象都交由容器来管理。

  • 服务消费方

   服务消费方就容易了,只需要知道注册中心地址,并引用服务提供方提供的接口,消费方调用服务实现如下所示:

package org.shirdrn.dubbo.consumer;import java.util.Arrays;
import java.util.List;import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.shirdrn.dubbo.api.ChatRoomOnlineUserCounterService;
import org.springframework.context.support.AbstractXmlApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class ChatRoomDubboConsumer {private static final Log LOG = LogFactory.getLog(ChatRoomDubboConsumer.class);public static void main(String[] args) throws Exception {AbstractXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:consumer.xml");try {context.start();ChatRoomOnlineUserCounterService chatRoomOnlineUserCounterService = (ChatRoomOnlineUserCounterService) context.getBean("chatRoomOnlineUserCounterService");         getMaxOnlineUserCount(chatRoomOnlineUserCounterService);              getRealtimeOnlineUserCount(chatRoomOnlineUserCounterService);              System.in.read();} finally {context.close();}}private static void getMaxOnlineUserCount(ChatRoomOnlineUserCounterService liveRoomOnlineUserCountService) {List<String> maxUserCounts = liveRoomOnlineUserCountService.getMaxOnlineUserCount(Arrays.asList(new String[] {"1482178010" , "1408492761", "1430546839", "1412517075", "1435861734"}), "20150327", "yyyyMMdd");LOG.info("After getMaxOnlineUserCount invoked: maxUserCounts= " + maxUserCounts);}private static void getRealtimeOnlineUserCount(ChatRoomOnlineUserCounterService liveRoomOnlineUserCountService)throws InterruptedException {String rooms = "1482178010,1408492761,1430546839,1412517075,1435861734";String onlineUserCounts = liveRoomOnlineUserCountService.queryRoomUserCount(rooms);LOG.info("After queryRoomUserCount invoked: onlineUserCounts= " + onlineUserCounts);}
}

 对应的配置文件为consumer.xml,内容如下所示:

<?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-3.0.xsdhttp://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"><dubbo:application name="chatroom-consumer" /><dubbo:registry address="zookeeper://zk1:2181?backup=zk2:2181,zk3:2181" /><dubbo:reference id="chatRoomOnlineUserCounterService" interface="org.shirdrn.dubbo.api.ChatRoomOnlineUserCounterService" version="1.0.0"><dubbo:method name="queryRoomUserCount" retries="2" /></dubbo:reference></beans>

 也可以根据需要配置dubbo:reference相关的属性值,也可以配置dubbo:method指定调用的方法的配置信息,详细配置属性可以参考Dubbo官方文档。

  原文链接请参见:http://shiyanjun.cn/archives/1075.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/457271.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如果我们不曾相遇

五月天的演唱会定的是9月10号&#xff0c;周六晚上7点。 而我&#xff0c;差不多&#xff0c;从一周前就开始准备了&#xff0c;因为公司最近在赶工&#xff0c;特别忙。为了周末不加班我提前一周就旁敲侧击地询问师父的时间安排&#xff0c;最后又耿直地告诉师父我的周末计划&…

win下php的memcached的安装与使用

1、memcache的php扩展与memcached服务器的区别&#xff1f; php要操作memcached就必须要安装memcache的扩展&#xff0c; 在http://windows.php.net/downloads/pecl/releases/memcache/下载相应版本安装。 而php要操作memcached就必须要有memcached的服务&#xff0c;不然没有服…

mysql 表的存储类型_MySQL数据表存储引擎类型及特性

数据表类型(存储引擎)常见引擎比对 特点 Myisam InnoDB Memory BDB Archive 存储限制 无穷制 64TB 有 没有 没有 事务安然 - 支撑 - 支撑 - 锁机制 表锁 行锁 表锁 页锁 行锁 B树索引 支撑 支撑 支撑 支撑 - 哈希索引 - 支撑 支撑 - - 全文索引 支撑 - - - - 集群索引 - 支撑 -…

ORM中的Model与DDD中的DomainModel

0.引言 在现有的系统开发中&#xff0c;大部分的系统应该都会用到ORM&#xff0c;无论用的是EF还是NHibernate。作为对象和持久化数据的桥梁&#xff0c;ORM确实非常方便&#xff0c;以至于在DDD的时候&#xff0c;我们很自然的将 ORM中的Model(实体)表达成DDD中的 DomainModel…

jsp java语法_JSP基础语法

Java JSP 的 JSP基础语法在本章中&#xff0c;我们将了解和学习JSP语法。并了解JSP开发涉及的简单语法(即元素)的基本用法。为了方便演示&#xff0c;使用Eclipse创建一个动态Web项目&#xff1a;jspsyntax&#xff0c;用于运行以下涉及到的示例代码。JSP的元素JSP的元素如下所…

iOS - Core Animation 核心动画

1、UIView 动画 具体讲解见 iOS - UIView 动画2、UIImageView 动画 具体讲解见 iOS - UIImageView 动画3、CADisplayLink 定时器 具体讲解见 iOS - OC NSTimer 定时器CADisplayLink 是一个能让我们以和屏幕刷新率相同的频率将内容画到屏幕上的定时器。我们在应用中创建一个新的…

【BZOJ 1597】 [Usaco2008 Mar]土地购买 (斜率优化)

1597: [Usaco2008 Mar]土地购买 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3601 Solved: 1322Description 农夫John准备扩大他的农场,他正在考虑N (1 < N < 50,000) 块长方形的土地. 每块土地的长宽满足(1 < 宽 < 1,000,000; 1 < 长 < 1,000,000). …

深入浅出学java_《深入浅出学JAVA开发初级》

整体说明&#xff1a;Java私塾的这一套视频是完全真实课堂录制&#xff0c;实际上课时间为十一天&#xff0c;主要内容包括&#xff1a;1&#xff1a;系统完整的学习Java的基础知识2&#xff1a;深入剖析重点知识点的理论3&#xff1a;超多的编程题目和程序讲解4&#xff1a;最…

Linux bashrc和profile的用途和区别

导读使用终端ssh登录Linux操作系统的控制台后&#xff0c;会出现一个提示符号&#xff08;例如&#xff1a;#或~&#xff09;&#xff0c;在这个提示符号之后可以输入命令&#xff0c;Linux根据输入的命令会做回应&#xff0c;这一连串的动作是由一个所谓的Shell来做处理。Shel…

Golang 特性简介

by sheepbao 主要大概介绍go语言的历史和特性&#xff0c;简单的入门。 来历 很久以前&#xff0c;有一个IT公司&#xff0c;这公司有个传统&#xff0c;允许员工拥有20%自由时间来开发实验性项目。在2007的某一天&#xff0c;公司的几个大牛&#xff0c;正在用c开发一些比较繁…

华为2017java笔试题_2017年java华为面试题

2017年java华为面试题通过HCNP认证&#xff0c;将证明您对中小型网络有全面深入的了解&#xff0c;掌握中小型网络的通用技术&#xff0c;并具备独立设计中小型网络以及使用华为路由交换设备实施设计的能力。下面是小编收集的关于java华为面试题&#xff0c;希望大家认真阅读!1…

java框架概念_java概念(2)

java概念(2)重载和重写重载&#xff1a;同一个类中&#xff0c;方法名相同&#xff0c;参数不同重写&#xff1a;父子类中&#xff0c;子类重新定义父类的方法多态​ 多态&#xff1a;同一种行为&#xff0c;不同的对象有不同的表现形式。​ 重载 编译时根据参数决定调用的方法…

CentOS(八)--crontab命令的使用方法

crontab命令常见于Unix和Linux的操作系统之中&#xff0c;用于设置周期性被执行的指令。该命令从标准输入设备读取指令&#xff0c;并将其存放于"crontab"文件中&#xff0c;以供之后读取和执行。 在Linux系统中&#xff0c;Linux任务调度的工作主要分为以下两类&…

有健忘症吗?

今天兴高采烈&#xff0c;早上空气不错&#xff0c; 但是骑自行车的我&#xff0c;还是得戴一个面罩。 半个小时后买了早餐&#xff0c; 一份炒粉、一豆浆&#xff0c;今天早上豆浆没有掉地上&#xff0c; 但是~~~~~~~~~~~~~~shit~~!~!~,居然忘记带要换的衣服了&#xff0c; …

下载java后缀的文件闪退_关于jarfile 打开闪退问题

后面才发现&#xff0c;原来是因为我把文件拖入了新建的文件夹&#xff0c;改变了路径&#xff0c;而且我的java环境没有配置好是全局变量&#xff0c;所以新建文件夹之后&#xff0c;就会出现找不到了路径&#xff0c;闪退的问题&#xff0c;&#xff0c;&#xff0c;还有就是…

java怎样写入五个人的成绩_用java输入5个学员姓名和分数,显示分数最高的学员姓名和分数?...

展开全部import java.util.Scanner;public class Student {private String stuname "";private float stuscore 0;public String getStuname() {e69da5e6ba9062616964757a686964616f31333335316633return stuname;}public void setStuname(String stuname) {this.s…

iOS 10 升级后无法真机测试 Could not find Developer Disk Image

&#xff0d;&#xff0d;&#xff0d;2016年9月20日更新 iOS 升级到10之后&#xff0c;你会发现无法进行真机测试了。这种情况我在iOS 8.4 、9.3更新的时候也遇到过。原因是Xcode 的DeviceSupport里面缺少了iOS 10的SDK。所以你可以选择将Xcode更新到最新版本就可以了&#xf…

java虚拟机参数优化_JAVA虚拟机JVM参数优化(2):垃圾收集算法选择

JAVA虚拟机JVM优化重要性&#xff0c;昨天JAVA虚拟机JVM参数优化(1)文章中已经描述&#xff0c;今天我们来讨论JAVA虚拟机在不同性能要求下如何选择三种垃圾收集算法。JVM内部结构如下图所示&#xff1a;串行收集用于单个线程执行垃圾收集的情况&#xff0c;在这种情况下相对它…

Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡、容错)

2019独角兽企业重金招聘Python工程师标准>>> 互联网的发展&#xff0c;网站应用的规模不断扩大&#xff0c;常规的垂直应用架构已无法应对&#xff0c;分布式服务架构以及流动计算架构势在必行&#xff0c;Dubbo是一个分布式服务框架&#xff0c;在这种情况下诞生的…