基于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.pswp.cn/news/457271.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/457271.shtml
英文地址,請注明出處:http://en.pswp.cn/news/457271.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

vue樣式中背景圖片路徑_vue打包css文件中背景圖片的路徑問題

vue-cli寫完的靜態頁面我們在node環境中引入沒有問題&#xff0c;但是打包后放在Apache環境下&#xff0c;路徑卻有問題了如一個簡單css語句.all_bg {background: url(../images/all_bg.png) 0 0 no-repeat;display: inline-block;overflow: hidden;background-size: 200px 300…

如果我們不曾相遇

五月天的演唱會定的是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;不然沒有服…

git 常用命令筆記

#提交代碼會加上用戶名和郵箱 git config --global user.name 名字 git config --global user.email 郵箱 git config --global color.ui true#列出所有配置 git config --list#創建一個repository(倉庫) git init #可以看到一個.git目錄 ls -A #復制一個已有的項目 git clone …

mysql 表的存儲類型_MySQL數據表存儲引擎類型及特性

數據表類型(存儲引擎)常見引擎比對 特點 Myisam InnoDB Memory BDB Archive 存儲限制 無窮制 64TB 有 沒有 沒有 事務安然 - 支撐 - 支撐 - 鎖機制 表鎖 行鎖 表鎖 頁鎖 行鎖 B樹索引 支撐 支撐 支撐 支撐 - 哈希索引 - 支撐 支撐 - - 全文索引 支撐 - - - - 集群索引 - 支撐 -…

78.Subsets

Given a set of distinct integers, nums, return all possible subsets. Note: The solution set must not contain duplicate subsets. For example,If nums [1,2,3], a solution is: [[3],[1],[2],[1,2,3],[1,3],[2,3],[1,2],[] ]昨天中秋加上頭非常痛&#xff0c;歇了一天…

python xyz_python中xyz坐標的歐幾里德距離

使用生成器表達式的簡單解決方案From PEP 289 Generator ExpressionsRationaleExperience with list comprehensions has shown their widespread utilitythroughout Python. However, many of the use cases do not need to have a full list created in memory. Instead, the…

[轉載]SYSCALL_DEFINE宏定義

來源:http://blog.csdn.net/p_panyuch/article/details/5648007 SYSCALL_DEFINE3 在何處定義&#xff1f; #define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__) #define SYSCALL_DEFINEx(x, sname, ...) / _…

java連接數據庫sql server_將SQL Server數據庫連接到Java

我的項目沒有使用任何IDE。整個編碼使用Textpad完成。所以我需要幫助連接sql server數據庫和我的項目。這是bean類&#xff0c;其中編寫了用于數據庫連接的業務邏輯。我已經安裝了SQL服務器并使用Windows身份驗證創建了一個名為“vt”的數據庫。我甚至為數據庫創建了dsn&#x…

ORM中的Model與DDD中的DomainModel

0.引言 在現有的系統開發中&#xff0c;大部分的系統應該都會用到ORM&#xff0c;無論用的是EF還是NHibernate。作為對象和持久化數據的橋梁&#xff0c;ORM確實非常方便&#xff0c;以至于在DDD的時候&#xff0c;我們很自然的將 ORM中的Model(實體)表達成DDD中的 DomainModel…

基礎總結

Unsafe Java線程池 HashCode 垃圾收集 關于引用&#xff08;弱引用、強引用等等&#xff09;轉載于:https://www.cnblogs.com/aquariusm/p/6340303.html

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 是一個能讓我們以和屏幕刷新率相同的頻率將內容畫到屏幕上的定時器。我們在應用中創建一個新的…

navicat 官方使用手冊,中文版,快捷鍵大全

2017年1月23日09:52:51 這個官方中文文檔很詳細 https://www.navicat.com.cn/manual/online_manual/cn/navicat/win_manual/index.html https://community.navicat.com/videos/cn 官方中文論壇部分視頻教程 快捷鍵 Navicat 主窗口 鍵動作CTRLG設置位置文件夾CTRL#&#xff08;#…

Linux inode與文件系統關系

inode只有在linux文件系統的概念&#xff08;ext3,ext4) 、inode節點數量與文件存儲的關系。 二、在文件系統初始化時設置合適的節點數量。 linux服務器在存儲文件小而數量多的情況下&#xff0c;需要考慮inode用完的情況。轉載于:https://www.cnblogs.com/lirunzhou/p/5883706…

評分系統 java_C自動評分系統

我無法按照規范完成作業 . 這是分配方案&#xff1a;大學迫切需要一個自動測試評分系統 . 使用C&#xff0c;為大學寫一個評分系統&#xff0c;并對至少五名學生的測試進行評分 . 要創建評分系統&#xff0c;請按照以下步驟操作&#xff1a;首先詢問測試中的問題數量然后詢問每…

當Terraform遇上ECS(一)——DataSource篇

背景 越來越多的公司已經熟知并運用“基礎設施即代碼”來構建和維護自己的云基礎設施。目前也有許多的自動化構建工具協助用戶通過腳本進行云資源的部署和生命周期的管理&#xff0c;如&#xff1a;Terraform、Ansible、Chef等。但是&#xff0c;在實施過程中&#xff0c;都遇到…

【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;最…

重定位與鏈接腳本

1.為什么需要重定位   位置無關編碼(PIC&#xff0c;position independent code)&#xff1a;匯編源文件被編碼成二進制可執行程序時編碼方式與位置&#xff08;內存地址&#xff09;無關。  位置有關編碼&#xff1a;匯編源碼編碼成二進制可執行程序后和內存地址是有關的。…