Spring Cloud微服務(wù)架構(gòu)升級(jí)總結(jié)

【編者的話】微服務(wù)的概念源于 2014 年 3 月 Martin Fowler 所寫的一篇文章“Microservices”赋访。文中內(nèi)容提到:微服務(wù)架構(gòu)是一種架構(gòu)模式颈抚,它提倡將單一應(yīng)用程序劃分成一組小的服務(wù)弄息,服務(wù)之間互相協(xié)調(diào)羽资、互相配合惊搏,為用戶提供最終價(jià)值怠益。

背景

應(yīng)用系統(tǒng)的架構(gòu)歷史

什么是微服務(wù)仪搔?

起源:微服務(wù)的概念源于2014年3月Martin Fowler所寫的一篇文章“Microservices”。文中內(nèi)容提到:微服務(wù)架構(gòu)是一種架構(gòu)模式蜻牢,它提倡將單一應(yīng)用程序劃分成一組小的服務(wù)烤咧,服務(wù)之間互相協(xié)調(diào)、互相配合抢呆,為用戶提供最終價(jià)值煮嫌。

通信方式:每個(gè)服務(wù)運(yùn)行在其獨(dú)立的進(jìn)程中,服務(wù)與服務(wù)間采用輕量級(jí)的通信機(jī)制互相溝通(通常是基于HTTP的RESTful API)抱虐。

微服務(wù)的常規(guī)定義:微服務(wù)是一種架構(gòu)風(fēng)格昌阿,一個(gè)大型復(fù)雜軟件應(yīng)用由一個(gè)或多個(gè)微服務(wù)組成。系統(tǒng)中的各個(gè)微服務(wù)可被獨(dú)立部署恳邀,各個(gè)微服務(wù)之間是松耦合的懦冰。每個(gè)微服務(wù)僅關(guān)注于完成一件任務(wù)。

把原來(lái)的一個(gè)完整的進(jìn)程服務(wù)轩娶,拆分成兩個(gè)或兩個(gè)以上的進(jìn)程服務(wù)儿奶,且互相之間存在調(diào)用關(guān)系,與原先單一的進(jìn)程服務(wù)相比鳄抒,就是“微服務(wù)”闯捎。(微服務(wù)是一個(gè)比較級(jí)的概念,而不是單一的概念)如果你想和更多微服務(wù)技術(shù)專家交流许溅,可以加我程序員交流QQ群:833145934瓤鼻,備注『?jiǎn)讨巍弧H豪锩恐芏加腥蚋鞔蠊镜淖罴褜?shí)踐以及行業(yè)最新動(dòng)態(tài)贤重。

微服務(wù)架構(gòu)的優(yōu)勢(shì)

  • 可擴(kuò)展性:在增加業(yè)務(wù)功能時(shí)茬祷,單一應(yīng)用架構(gòu)需要在原先架構(gòu)的代碼基礎(chǔ)上做比較大的調(diào)整,而微服務(wù)架構(gòu)只需要增加新的微服務(wù)節(jié)點(diǎn)并蝗,并調(diào)整與之有關(guān)聯(lián)的微服務(wù)節(jié)點(diǎn)即可祭犯。在增加業(yè)務(wù)響應(yīng)能力時(shí)秸妥,單一架構(gòu)需要進(jìn)行整體擴(kuò)容,而微服務(wù)架構(gòu)僅需要擴(kuò)容響應(yīng)能力不足的微服務(wù)節(jié)點(diǎn)沃粗。

  • 容錯(cuò)性:在系統(tǒng)發(fā)生故障時(shí)粥惧,單一應(yīng)用架構(gòu)需要進(jìn)行整個(gè)系統(tǒng)的修復(fù),涉及到代碼的變更和應(yīng)用的啟停最盅,而微服務(wù)架構(gòu)僅僅需要針對(duì)有問(wèn)題的服務(wù)進(jìn)行代碼的變更和服務(wù)的啟停突雪。其他服務(wù)可通過(guò)重試、熔斷等機(jī)制實(shí)現(xiàn)應(yīng)用層面的容錯(cuò)涡贱。

  • 技術(shù)選型靈活:微服務(wù)架構(gòu)下咏删,每個(gè)微服務(wù)節(jié)點(diǎn)可以根據(jù)完成需求功能的不同,自由選擇最適合的技術(shù)棧问词,即使對(duì)單一的微服務(wù)節(jié)點(diǎn)進(jìn)行重構(gòu)督函,成本也非常低。

  • 開(kāi)發(fā)運(yùn)維效率更高:每個(gè)微服務(wù)節(jié)點(diǎn)都是一個(gè)單一進(jìn)程戏售,都專注于單一功能侨核,并通過(guò)定義良好的接口清晰表述服務(wù)邊界。由于體積小灌灾、復(fù)雜度低,每個(gè)微服務(wù)可由一個(gè)小規(guī)模團(tuán)隊(duì)或者個(gè)人完全掌控悲柱,易于保持高可維護(hù)性和開(kāi)發(fā)效率锋喜。

Spring Cloud作為目前最流行的微服務(wù)開(kāi)發(fā)框架,不是采用了Spring Cloud框架就實(shí)現(xiàn)了微服務(wù)架構(gòu)豌鸡,具備了微服務(wù)架構(gòu)的優(yōu)勢(shì)嘿般。正確的理解是使用Spring Cloud框架開(kāi)發(fā)微服務(wù)架構(gòu)的系統(tǒng),使系統(tǒng)具備微服務(wù)架構(gòu)的優(yōu)勢(shì)(Spring Cloud就像工具涯冠,還需要“做”的過(guò)程)炉奴。

什么是Spring Boot?什么是Spring Cloud蛇更?

Spring Boot框架是由Pivotal團(tuán)隊(duì)提供的全新框架瞻赶,其設(shè)計(jì)目的是用來(lái)簡(jiǎn)化基于Spring應(yīng)用的初始搭建以及開(kāi)發(fā)過(guò)程。SpringBoot框架使用了特定的方式來(lái)進(jìn)行應(yīng)用系統(tǒng)的配置派任,從而使開(kāi)發(fā)人員不再需要耗費(fèi)大量精力去定義模板化的配置文件砸逊。

Spring Cloud是一個(gè)基于Spring Boot實(shí)現(xiàn)的云應(yīng)用開(kāi)發(fā)工具,它為基于JVM的云應(yīng)用開(kāi)發(fā)中的配置管理掌逛、服務(wù)注冊(cè)师逸,服務(wù)發(fā)現(xiàn)、斷路器豆混、智能路由篓像、微代理动知、控制總線、全局鎖员辩、決策競(jìng)選拍柒、分布式會(huì)話和集群狀態(tài)管理等操作提供了一種簡(jiǎn)單的開(kāi)發(fā)方式。

微服務(wù)屈暗、Spring Boot拆讯、Spring Cloud三者之間的關(guān)系

思想:微服務(wù)是一種架構(gòu)的理念,提出了微服務(wù)的設(shè)計(jì)原則养叛,從理論為具體的技術(shù)落地提供了指導(dǎo)思想种呐。
腳手架:Spring Boot是一套快速配置腳手架,可以基于Spring Boot快速開(kāi)發(fā)單個(gè)微服務(wù)弃甥。
多個(gè)組件的集合:Spring Cloud是一個(gè)基于Spring Boot實(shí)現(xiàn)的服務(wù)治理工具包爽室;Spring Boot專注于快速、方便集成的單個(gè)微服務(wù)個(gè)體淆攻;Spring Cloud關(guān)注全局的服務(wù)治理框架阔墩。

技術(shù)解析

Everything is jar,Everything is http
Spring Boot通過(guò)@SpringBootApplication注解標(biāo)識(shí)為Spring Boot應(yīng)用程序瓶珊。所有的應(yīng)用都通過(guò)jar包方式編譯啸箫,部署和運(yùn)行。
@SpringBootApplication 
public class Application {     
private static final Logger LOGGER = LoggerFactory.getLogger(Application.class);     
public static void main(String[] args) {         
    SpringApplication.run(Application.class, args);         
    LOGGER.info(”啟動(dòng)成功伞芹!");     
} 
} 

每個(gè)Spring Boot的應(yīng)用都可以通過(guò)內(nèi)嵌Web容器的方式提供http服務(wù)忘苛,僅僅需要在pom文件中依賴spring-boot-start-web即可,原則上微服務(wù)架構(gòu)希望每個(gè)獨(dú)立節(jié)點(diǎn)都提供http服務(wù)唱较。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
Spring boot Task任務(wù)啟動(dòng)和定時(shí)任務(wù)
在Spring Boot需要啟動(dòng)任務(wù)時(shí)扎唾,只要繼承CommandLineRunner接口實(shí)現(xiàn)其run方法即可。
@SpringBootApplication 
public class ClientDataListener implements CommandLineRunner
public void run(String... strings) throws Exception {     
    clientInfoListenerHandler(); 
}
} 

在Spring Boot需要執(zhí)行定時(shí)任務(wù)時(shí)南缓,只需要在定時(shí)任務(wù)方法上增加@Scheduled(cron = “0 15 0 * * ?”)注解(支持標(biāo)準(zhǔn)cron表達(dá)式)胸遇,并且在服務(wù)啟動(dòng)類上增加@EnableScheduling的注解即可汉形。

@SpringBootApplication
@EnableScheduling
public class Application {     
private static final Logger LOGGER = LoggerFactory.getLogger(Application.class);     
public static void main(String[] args) {         
    SpringApplication.run(Application.class, args);         
    LOGGER.info(”啟動(dòng)成功!");     
} 
} 
// some class
@Scheduled(cron = "0 15 0 * * ?")
public void someTimeTask() {
***
} 
Spring boot Actuator監(jiān)控

Actuator是Spring Boot提供的對(duì)應(yīng)用系統(tǒng)自身進(jìn)行監(jiān)控的組件获雕,在引入spring-boot-start-web基礎(chǔ)上引入spring-boot-starter-actuator即可薄腻。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
Spring cloud Config配置中心

在我們實(shí)現(xiàn)微服務(wù)架構(gòu)時(shí),每個(gè)微服務(wù)節(jié)點(diǎn)都需要自身的相關(guān)配置數(shù)據(jù)項(xiàng)届案,當(dāng)節(jié)點(diǎn)眾多,維護(hù)就變得非常困難,因此需要建立一個(gè)中心配置服務(wù)咐蚯。

Spring Cloud Config分為兩部分。Spring Cloud Config server作為一個(gè)服務(wù)進(jìn)程弄贿,Spring Cloud Config File為配置文件存放位置春锋。

Spring cloud Eureka 服務(wù)注冊(cè)中心

服務(wù)注冊(cè)的概念早在微服務(wù)架構(gòu)之前就出現(xiàn)了差凹,微服務(wù)架構(gòu)更是把原先的單一應(yīng)用節(jié)點(diǎn)拆分成非常多的微服務(wù)節(jié)點(diǎn)∥D颍互相之間的調(diào)用關(guān)系會(huì)非常復(fù)雜,Spring Cloud Eureka作為注冊(cè)中心肺孤,所有的微服務(wù)都可以將自身注冊(cè)到Spring Cloud Eureka進(jìn)行統(tǒng)一的管理和訪問(wèn)(Eureka和Zookeeper不同济欢,在AOP原則中選擇了OP赠堵,更強(qiáng)調(diào)服務(wù)的有效性)

Spring Cloud Zuul服務(wù)端智能路由

當(dāng)我們把所有的服務(wù)都注冊(cè)到Eureka(服務(wù)注冊(cè)中心)以后法褥,就涉及到如何調(diào)用的問(wèn)題。Spring Cloud Zuul是Spring Cloud提供的服務(wù)端代理組件杂靶,可以看做是網(wǎng)關(guān)酱鸭,Zuul通過(guò)Eureka獲取到可用的服務(wù)垛吗,通過(guò)映射配置,客戶端通過(guò)訪問(wèn)Zuul來(lái)訪問(wèn)實(shí)際需要需要訪問(wèn)的服務(wù)怯屉。所有的服務(wù)通過(guò)spring.application.name做標(biāo)識(shí),不同IP地址赌躺,相同spring.application.name就是一個(gè)服務(wù)集群羡儿。當(dāng)我們?cè)黾右粋€(gè)相同spring.application.name的節(jié)點(diǎn),Zuul通過(guò)和Eureka通信獲取新增節(jié)點(diǎn)的信息實(shí)現(xiàn)智能路由,增加該類型服務(wù)的響應(yīng)能力悄泥。

Spring cloud Ribbon客戶端智能路由

與Spring Cloud Zuul的服務(wù)端代理相對(duì)應(yīng)肤粱,Spring Cloud Ribbon提供了客戶端代理。在服務(wù)端代理中鸥鹉,客戶端并不需要知道最終是哪個(gè)微服務(wù)節(jié)點(diǎn)為之提供服務(wù),而客戶端代理獲取實(shí)質(zhì)提供服務(wù)的節(jié)點(diǎn)毁渗,并選擇一個(gè)進(jìn)行服務(wù)調(diào)用瓢姻。Ribbon和Zuul相似,也是通過(guò)和Eureka(服務(wù)注冊(cè)中心)進(jìn)行通信來(lái)實(shí)現(xiàn)客戶端智能路由绎狭。

Spring Cloud Sleuth分布式追蹤

Spring Cloud Zipkin調(diào)用鏈

Spring Cloud Feign http客戶端

Spring Cloud Feign是一種聲明式褥傍、模板化的http客戶端。 使用Spring Cloud Feign請(qǐng)求遠(yuǎn)程服務(wù)時(shí)能夠像調(diào)用本地方法一樣恍风,讓開(kāi)發(fā)者感覺(jué)不到這是遠(yuǎn)程方法(Feign集成了Ribbon做負(fù)載均衡)。

把遠(yuǎn)程服務(wù)和本地服務(wù)做映射:

@FeignClient(name = "rabbitmq-http", url = "${SKYTRAIN_RABBITMQ_HTTP}") 
public interface TaskService {     
@RequestMapping(value = "/api/queues", method = RequestMethod.GET)     
public String query(@RequestHeader("Authorization") String token); 
} 

以調(diào)用本地服務(wù)的方式調(diào)用遠(yuǎn)程服務(wù):

@Autowired 
private TaskService taskService; 
private String queryRabbitmqStringInfo() {     
byte[] credentials = Base64 .encodeBase64((rabbitmqHttpUserName + ":" + rabbitmqHttpPassword).getBytes(StandardCharsets.UTF_8));     
String token = "Basic " + new String(credentials, StandardCharsets.UTF_8);     
return taskService.query(token); 
} 

Spring cloud Hystrix斷路器

微服務(wù)實(shí)踐

我們開(kāi)發(fā)的幾個(gè)微服務(wù)組件:應(yīng)用管理中心

應(yīng)用管理中心可以對(duì)每個(gè)已經(jīng)注冊(cè)的微服務(wù)節(jié)點(diǎn)進(jìn)行停止凯楔,編譯锦募,打包,部署虐骑,啟動(dòng)的完整的上線操作赎线。

我們開(kāi)發(fā)的幾個(gè)微服務(wù)組件:ZooKeeper數(shù)據(jù)查詢中心

ZooKeeper數(shù)據(jù)查詢中心根據(jù)ZooKeeper地址、端口垂寥、命令獲取ZooKeeper數(shù)據(jù)信息另锋。

我們開(kāi)發(fā)的幾個(gè)微服務(wù)組件:微服務(wù)健康檢測(cè)中心

健康檢測(cè)中心周期性檢查每個(gè)微服務(wù)的狀態(tài)盏缤,當(dāng)發(fā)現(xiàn)有微服務(wù)狀態(tài)處于DOWN或連接超時(shí)時(shí),觸發(fā)報(bào)警唉铜。

我們開(kāi)發(fā)的幾個(gè)微服務(wù)組件:定時(shí)任務(wù)查詢中心
// 在BeanPostProcessor子類中攔截
@Component
public class SkytrainBeanPostProcessor implements BeanPostProcessor, Ordered {
***
/**
 * Bean 實(shí)例化之后進(jìn)行的處理
 */
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    beanPostProcessor.postProcessAfter(bean, beanName);
    return bean;
}
***
}
// 攔截后獲取定時(shí)任務(wù)注解
***
public Object postProcessAfter(Object bean, String beanName) {
Class targetClass = AopUtils.getTargetClass(bean);
Map annotatedMethods = MethodIntrospector.selectMethods(targetClass,
        new MethodIntrospector.MetadataLookup() {

            public Set inspect(Method method) {

                Set scheduledMethods = AnnotatedElementUtils.getMergedRepeatableAnnotations(method,
                        Scheduled.class, Schedules.class);
                return (!scheduledMethods.isEmpty() ? scheduledMethods : null);
            }
        });
if (!annotatedMethods.isEmpty()) {
    String className = targetClass.getName();
    for (Map.Entry entry : annotatedMethods.entrySet()) {
        Method method = entry.getKey();
        for (Scheduled scheduled : entry.getValue()) {
            String key = className + ":" + method.getName();
            String value = scheduled.toString();
            taskInfos.put(key, value);
        }
    }
}
return null;
}
***

// 獲取定時(shí)任務(wù)后注冊(cè)
***
public void taskRegister() {
String nodeInfo = ipAddress + ":" + serverPort + ":";
try {
    /**
     * 定時(shí)任務(wù)
     */
    Map infos = taskInfos;
    for (Entry item : infos.entrySet()) {
        String taskId = nodeInfo + item.getKey();
        String taskParameter = item.getValue();
        JSONObject info = new JSONObject();
        info.put("taskId", taskId);
        info.put("taskParameter", taskParameter);
        info.put("applicationName", applicationName);
        info.put("taskType", "schedule");
        LOGGER.info(info.toString());
        zooKeeperExecutor.createZKNode(SKYTRAIN_TASK_ZKNODE_PREFIX + taskId, info.toString());
    }
}
catch (Exception ex) {
    LOGGER.error("", ex);
}
}
***

微服務(wù)的分類

  • 微服務(wù)平臺(tái)組件
  • 公共服務(wù)組件
  • 基礎(chǔ)服務(wù)組件/業(yè)務(wù)服務(wù)組件

整體微服務(wù)架構(gòu)圖

敬請(qǐng)關(guān)注竞惋,簡(jiǎn)書博客「AI喬治」獲取最新文章
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末灰嫉,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子讼撒,更是在濱河造成了極大的恐慌,老刑警劉巖钳幅,帶你破解...
    沈念sama閱讀 216,919評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件炎滞,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡钠导,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,567評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門牡属,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)扼睬,“玉大人,你說(shuō)我怎么就攤上這事⊥郑” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 163,316評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵蝇完,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我短蜕,道長(zhǎng),這世上最難降的妖魔是什么岖研? 我笑而不...
    開(kāi)封第一講書人閱讀 58,294評(píng)論 1 292
  • 正文 為了忘掉前任警检,我火速辦了婚禮,結(jié)果婚禮上扇雕,老公的妹妹穿的比我還像新娘。我一直安慰自己镶奉,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,318評(píng)論 6 390
  • 文/花漫 我一把揭開(kāi)白布鸽凶。 她就那樣靜靜地躺著移国,像睡著了一般。 火紅的嫁衣襯著肌膚如雪迹缀。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,245評(píng)論 1 299
  • 那天票摇,我揣著相機(jī)與錄音砚蓬,去河邊找鬼。 笑死灰蛙,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的物延。 我是一名探鬼主播仅父,決...
    沈念sama閱讀 40,120評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼浑吟,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼耗溜!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起抖拴,我...
    開(kāi)封第一講書人閱讀 38,964評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤城舞,失蹤者是張志新(化名)和其女友劉穎轩触,沒(méi)想到半個(gè)月后家夺,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,376評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡榨为,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,592評(píng)論 2 333
  • 正文 我和宋清朗相戀三年煌茴,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片矩乐。...
    茶點(diǎn)故事閱讀 39,764評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡回论,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出傀蓉,到底是詐尸還是另有隱情,我是刑警寧澤误甚,帶...
    沈念sama閱讀 35,460評(píng)論 5 344
  • 正文 年R本政府宣布谱净,位于F島的核電站,受9級(jí)特大地震影響壕探,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜派继,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,070評(píng)論 3 327
  • 文/蒙蒙 一捻艳、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧认轨,春花似錦、人聲如沸恩急。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,697評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)纯续。三九已至,卻和暖如春猬错,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背显沈。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,846評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工逢唤, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人智玻。 一個(gè)月前我還...
    沈念sama閱讀 47,819評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像盖彭,于是被迫代替她去往敵國(guó)和親页滚。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,665評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 一.應(yīng)用系統(tǒng)的架構(gòu)歷史 二.什么是微服務(wù)隧熙? 2.1 微服務(wù)概述 起源:微服務(wù)的概念源于 2014 年 3 月 Ma...
    不想當(dāng)碼農(nóng)的程序員閱讀 1,455評(píng)論 0 21
  • 微服務(wù)架構(gòu)模式的核心在于如何識(shí)別服務(wù)的邊界幻林,設(shè)計(jì)出合理的微服務(wù)音念。但如果要將微服務(wù)架構(gòu)運(yùn)用到生產(chǎn)項(xiàng)目上躏敢,并且能夠發(fā)揮...
    java菜閱讀 2,949評(píng)論 0 6
  • 前言 現(xiàn)在研發(fā)的項(xiàng)目啟動(dòng)今已近一年之久,期間從項(xiàng)目屬性件余、人員規(guī)模、系統(tǒng)定位等方面都發(fā)生了很大的變化旬渠,而且是越變?cè)胶?..
    孫振強(qiáng)閱讀 12,293評(píng)論 1 58
  • 早上賴床了端壳,這不是好事,過(guò)年之后狀態(tài)一直不太好更哄。 忽然早起一個(gè)詞,間歇性努力成翩,看來(lái)我有點(diǎn)陷入這樣的狀態(tài)了,雖然沒(méi)有...
    小藍(lán)的練習(xí)本閱讀 133評(píng)論 0 0
  • 積累與體悟(一) 1.政治建設(shè)決定方向 十九大黨對(duì)一切工作的領(lǐng)導(dǎo)把方向栅炒。 2.善用比喻术羔。打虎赢赊、拍蠅级历、獵狐,壓倉(cāng)石寥殖,...
    陳娘來(lái)閱讀 107評(píng)論 0 1