日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > javascript >内容正文

javascript

Spring web应用最大的败笔

發(fā)布時(shí)間:2023/12/19 javascript 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring web应用最大的败笔 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

第一篇 介紹下IOC DI

Spring主要是業(yè)務(wù)層框架,現(xiàn)在已經(jīng)發(fā)展成為一個(gè)完整JavaEE開(kāi)發(fā)框架,它的主要特點(diǎn)是IoC DI和AOP等概念的融合,強(qiáng)項(xiàng)在面向切面AOP。推出之初因?yàn)镮oc/AOP等新設(shè)計(jì)理念值得框架設(shè)計(jì)者學(xué)習(xí),現(xiàn)在已經(jīng)成為Java世界主流框架,從其2.0引入auto-wired自動(dòng)配對(duì)以后,開(kāi)發(fā)效率大大提高,SpringMVC以簡(jiǎn)化和REST風(fēng)格著稱。Struts + Spring + Hibernate 號(hào)稱SSH框架是JavaEE經(jīng)典開(kāi)發(fā)組合。Spring是于2003 年興起的一個(gè)輕量級(jí)的Java開(kāi)源框架框架,由Rod Johnson 在其著作Expert One-On-One J2EE Development and Design中闡述的部分理念和原型衍生而來(lái)。Rod Johnson 對(duì)Java EE正統(tǒng)框架臃腫、低效、脫離現(xiàn)實(shí)的種種現(xiàn)狀提出了質(zhì)疑,并積極尋求探索革新之道。Spring相比EJB,重新重視和定義了POJO.

平時(shí),我們需要生成一個(gè)對(duì)象,使用new語(yǔ)法,如一個(gè)類為Apublic class A{public void myMethod(){System.out.println("hello");} }如果我們?cè)贐中調(diào)用A,那么如下代碼: public class B{public void invoke(){A a = new A();a.myMethod();} }

每次執(zhí)行invoke方法時(shí),都要生成一個(gè)A對(duì)象,如果A對(duì)象代碼較長(zhǎng),這是費(fèi)時(shí)的事
情。于是有如下寫(xiě)法:
public class B{
  A a = new A();
  public void invoke(){
    a.myMethod();
  }
}

將A對(duì)象變成B的類屬性。 如果我們不想在B中實(shí)現(xiàn)A的實(shí)例,也就是不想立即new A(),而是想通過(guò)外界傳入, 注意,如果你想知道為什么,這里涉及到設(shè)計(jì)模式以及解耦等因素,可詳細(xì)參考 GoF 23 種設(shè)計(jì)模式。

如果想讓A的實(shí)例從外界傳入,有兩種寫(xiě)法:
public class B{
  A a;
  public void setA(A a){
    this.a = a;
  }
  public A getA(){
    return a;
  }
  public void invoke(){
    a.myMethod();
  }
}
這種寫(xiě)法,A并沒(méi)有被實(shí)例化,需要通過(guò)外界調(diào)用setA方法,將A的對(duì)象實(shí)例賦入B中. 或者通過(guò)B的構(gòu)造函數(shù)傳入,如下:
public class B{
  A a;
  public B(A a){
    this.a = a;
  }
  public void invoke(){
    a.myMethod();
  }
}
上述兩種寫(xiě)法在編程中是經(jīng)常發(fā)生的,B作為調(diào)用者,A是被調(diào)用者,A的實(shí)例化不在調(diào)用者B內(nèi)部中完成,而是通過(guò)構(gòu)造函數(shù)或setXXX方法賦值進(jìn)來(lái),這種方式我們稱為依賴 性注射(IoC 模式),B 和A 的依賴聯(lián)系是通過(guò)構(gòu)造函數(shù)或setXXX 方法賦值進(jìn)來(lái),這樣, 最大程度解耦了調(diào)用者B和被調(diào)用者A之間的耦合聯(lián)系。Spring?IOC三種注入方式(接口注入、setter注入、構(gòu)造器注入)

Spring如何實(shí)現(xiàn)依賴注射:上文提到,A的實(shí)例化不在調(diào)用者B內(nèi)部中完成,而是通過(guò)構(gòu)造函數(shù)或setXXX 方法賦 值進(jìn)來(lái),Spring實(shí)際就是完成這個(gè)賦值的過(guò)程。 為了讓Spring自動(dòng)完成B代碼中的A的實(shí)例化,需要通過(guò)配置文件告訴Spring有關(guān)A 的類的屬性,這個(gè)配置是applicationContext.xml文件。 在 applicationContext.xml中,我們先定義JavaBeans為B的配置:

在 applicationContext.xml中,我們先定義JavaBeans為B的配置: <beans><bean id="b" class="springsimple.B"/> </beans> 這是最常用的JavaBeans的定義,id相當(dāng)于對(duì)象名,當(dāng)前文件應(yīng)該是唯一,如果你有Jsp 編程經(jīng)驗(yàn),這非常類似于Jsp里調(diào)用JavaBeans語(yǔ)句: <jsp:userBeans id="b" class="springsimple.B"/>再在applicationContext.xml定義A的配置如下: <beans><bean id="b" class="springsimple.B"/><bean id="a" class="springsimple.A"/> </beans> 這樣我們告訴Spring我們有兩個(gè)JavaBeans,現(xiàn)在解決關(guān)鍵問(wèn)題,B代碼中還調(diào)用了A, 那么如何讓Spring將A的實(shí)例注射到B中?使用Spring配置的property語(yǔ)法。具體配置如下: <beans><bean id="b" class="springsimple.B"><property name="a"><ref local="a" /></property> <!— 增加這一行--> </bean><bean id="a" class="springsimple.A" /> </beans>
增加一行說(shuō)明:B 的屬性a 指向了a,這樣,Spring 會(huì)知道B 中屬性a 的實(shí)例就是 springsimple.A,在B實(shí)例化時(shí)將會(huì)將B中的a 實(shí)現(xiàn)實(shí)例化,這是通過(guò)setA方法注射進(jìn)入。 注意,property name="a"中的a 是setA字符中去掉set 后的字符串,這個(gè)字符串第一個(gè)必須是小寫(xiě),例如,如果B中有setOneA方法,那么,配置文件應(yīng)該是property name="oneA"。

在程序中調(diào)用 Spring 前面我們寫(xiě)了兩個(gè)程序: B類和A類,并且寫(xiě)了配置文件applicationContext.xml,下面我們就可以運(yùn)行B類的invoke方法。
1. 首先,將Spring配置到Web容器中。Spring框架是運(yùn)行在Web容器中,所以,我們需要配置Web容器的配置文件web.xml,告訴Web容器有關(guān)Spring的配置文件名,這里取為applicationContext.xml,當(dāng)然可以取其他名稱,如下:
  <web-app>
    <display-name>WebModule1</display-name>
    <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>
    <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
  </web-app>
除了配置/WEB-INF/applicationContext.xml 文件, 還需要加入一個(gè)ContextLoaderListener,用于加載Spring配置文件,并實(shí)現(xiàn)初始化工作。將Spring注冊(cè)(寄 存)到Web 容器,這樣,在一個(gè)Web 容器中,只有一個(gè)Spring 應(yīng)用框架,我們可以借助 Spring框架實(shí)現(xiàn)Singleton全局。

在 Web 層應(yīng)用程序中使用Spring。前面已經(jīng)配置成功后,就可以在Web 層的Servlet或Jsp中調(diào)用訪問(wèn)Spring了,如果你編制的是一個(gè)Servlet/Jsp 程序,那么在你的Servlet/Jsp 使用下面的代碼通過(guò)Spring 創(chuàng)建B 的實(shí)例:

如果你編制的是一個(gè)Servlet/Jsp 程序,那么在你的Servlet/Jsp 使用下面的代碼通過(guò)Spring 創(chuàng)建B 的實(shí)例:

ServletContext servletContext =this.getServletContext(); WebApplicationContext appContext = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext); B b = (B) appContext.getBean("b");
上面基本是兩句,首先獲得WebApplicationContext實(shí)例,然后從WebApplicationContext
實(shí)例中獲得B的實(shí)例。 如果你使用的是Web 層應(yīng)用框架,如Struts或Tapestry,除了Spring說(shuō)明提供特殊方便的調(diào)用方式,你需要從這個(gè)框架中獲得當(dāng)前Servlet容器ServletContext實(shí)例,再調(diào)用上面代碼即可。

第二篇 回答幾個(gè)概念

????

  先來(lái)看看Spring的框架結(jié)構(gòu)。Spring是一個(gè)IOC和AOP的開(kāi)發(fā)框架和平臺(tái)。Spring的特點(diǎn):輕量,Spring?在大小和透明度上是輕量的,Spring基本核心版本大概只有1M,處理開(kāi)銷也非常小。IoC:?Spring使用IOC實(shí)現(xiàn)松耦合,對(duì)象不是自己主動(dòng)去尋找依賴而是依賴主動(dòng)推給了自己。AOP :?Spring支持面向方面編程,從業(yè)務(wù)邏輯中分離關(guān)注,能夠?qū)崿F(xiàn)聚焦開(kāi)發(fā)。容器:?Spring?容器包含和管理應(yīng)用對(duì)象的生命周期。框架 :?Spring提供最內(nèi)核的功能,其余留給開(kāi)發(fā)者自己開(kāi)發(fā)。?

  Spring的核心容器模塊:它提供基本功能的Spring框架。在此模塊中的BeanFactory是任何基于Spring的應(yīng)用程序的心臟。整個(gè)框架是建立在本模塊的基礎(chǔ)之上。該模塊生成Spring容器。

  applicationContext說(shuō)明,應(yīng)用程序上下文模塊使得Spring成為了一個(gè)框架。該模塊擴(kuò)展了BeanFactory的概念,國(guó)際化(I18N)消息,應(yīng)用程序生命周期事件,和驗(yàn)證提供支持。此模塊還提供了許多的企業(yè)服務(wù),例如JNDI訪問(wèn),EJB集成,遠(yuǎn)程和調(diào)度。它還提供了其他框架的支持。?

  Aop模塊:該AOP模塊用于Spring的應(yīng)用程序開(kāi)發(fā)方面。提供了大部分AOP聯(lián)盟的支持,以確保Spring和其它AOP框架之間的互操作性。此模塊還引入元數(shù)據(jù)編程。使用Spring的元數(shù)據(jù)支持我們的源代碼,通過(guò)引入元注釋,指導(dǎo)我們具體在哪里實(shí)現(xiàn)方面編程。

  JDBC和DAO抽象模塊:使用這個(gè)模塊,我們可以保持干凈和簡(jiǎn)單的數(shù)據(jù)庫(kù)的代碼,并防止失敗關(guān)閉數(shù)據(jù)庫(kù)資源等問(wèn)題。基于多個(gè)數(shù)據(jù)庫(kù)服務(wù)器的出錯(cuò)信息之上建立的一個(gè)新的有意義的異常層。此外,該模塊使用Spring的AOP模塊實(shí)現(xiàn)事務(wù)管理。

  對(duì)象關(guān)系數(shù)據(jù)庫(kù)映射整合模塊:Spring支持使用一個(gè)對(duì)象/關(guān)系映射(ORM)工具,基于JDBC提供ORM模塊。配合一些流行的ORM框架,包括Hibernate,JDO和iBATIS SQL映射。 Spring的事務(wù)管理也支持這些ORM框架以及JDBC。

  Web模塊:該模塊是建立在應(yīng)用上下文模塊之上,提供了一個(gè)基于Web應(yīng)用的上下文。此模塊還包含幾個(gè)面向Web的任務(wù),比如多個(gè)文件上傳和將請(qǐng)求參數(shù)透明地綁定到你的業(yè)務(wù)對(duì)象。它也包含與Jakarta Struts的集成支持。

  SpringMVC:Spring提供了一個(gè)全功能的構(gòu)建Web應(yīng)用程序的MVC框架。雖然Spring可以很容易地集成到其他的MVC框架,如Struts,Spring的MVC框架使用IOC將控制器邏輯從業(yè)務(wù)對(duì)象中干凈分離。它還允許您以聲明方式綁定請(qǐng)求參數(shù)到你的業(yè)務(wù)對(duì)象。它還可以利用Spring的其他服務(wù),如本地化消息和驗(yàn)證。

  BeanFactory:一個(gè)BeanFactory是工廠模式的實(shí)現(xiàn),使用反轉(zhuǎn)控制將從應(yīng)用程序的配置和依賴性從應(yīng)用程序代碼中分離。?Spring配置文件:Spring的配置文件是一個(gè)XML文件。此文件中包含的類信息,并描述這些類是如何配置,并實(shí)現(xiàn)相互的依賴導(dǎo)入。

Bean的生命周期:Spring容器從XML中發(fā)現(xiàn)一個(gè)Bean的定義,然后初始化創(chuàng)建它們 使用依賴注入,Spring將這個(gè)Bean中需要的屬性進(jìn)行導(dǎo)入。 如果這個(gè)Bean實(shí)現(xiàn) BeanNameAware 接口, 工廠將調(diào)用setBeanName() 傳遞Bean的ID。 如果bean實(shí)現(xiàn)BeanFactoryAware,工廠將調(diào)用 setBeanFactory(), 將自己的實(shí)例傳給它。 如果這個(gè)bean有 BeanPostProcessors 關(guān)聯(lián),他們的post- ProcessBeforeInitialization()方法將被調(diào)用。 如果這個(gè)Bean有一個(gè)初始init方法,它將被調(diào)用。 最后,如果有關(guān)聯(lián)對(duì)象 BeanPostProcessors ,postProcessAfterInitialization()方法將被調(diào)用。

  一個(gè)簡(jiǎn)單的Spring應(yīng)用程序包括:這些應(yīng)用程序像任何Java應(yīng)用程序。它們是由多個(gè)類組成,每個(gè)類執(zhí)行應(yīng)用程序內(nèi)的一個(gè)特定的功能。這些類的配置是通過(guò)一個(gè)XML文件向?qū)Ψ綄?dǎo)入依賴。此XML文件描述如何配置類,稱為Spring配置文件。

第三篇 web應(yīng)用的敗筆

開(kāi)發(fā)人員在使用Spring應(yīng)用是非常擅長(zhǎng)談?wù)撘蕾囎⑷氲暮锰帯2恍业氖?#xff0c;他們不是那么真的利用它的好處,如單一職責(zé)原則,分離關(guān)注原則。如果我們一起來(lái)看看大部分Spring的Web應(yīng)用程序,常見(jiàn)的錯(cuò)誤的設(shè)計(jì)如下:

  1.領(lǐng)域模型對(duì)象用來(lái)存儲(chǔ)應(yīng)用的數(shù)據(jù)(當(dāng)作DTO使用),領(lǐng)域模型是貧血模型這樣的反模式。
  2.服務(wù)層每個(gè)實(shí)體有一個(gè)服務(wù)。

問(wèn)題是這樣很普遍,錯(cuò)誤在哪里呢?
Spring的web應(yīng)用程序之所以這樣是因?yàn)樗麄冏鍪挛锏姆绞揭恢倍际沁@樣做的,老習(xí)慣難改,特別是如果他們是高級(jí)開(kāi)發(fā)人員或軟件架構(gòu)師,這些人捍衛(wèi)這樣做的論據(jù)之一是:我們的應(yīng)用程序遵循關(guān)注分離的原則,因?yàn)樗呀?jīng)被分為若干層,每個(gè)層有自己的特定職責(zé)。
  1. Web層負(fù)責(zé)處理用戶輸入,并返回正確的響應(yīng)返回給用戶。 web層與服務(wù)層通信。
  2.服務(wù)層作為一個(gè)事務(wù)邊界。它也負(fù)責(zé)授權(quán)和包含我們的應(yīng)用程序的業(yè)務(wù)邏輯。服務(wù)層管理的域模型對(duì)象,并與其他服務(wù)和存儲(chǔ)庫(kù)層進(jìn)行通信。
  3.存儲(chǔ)庫(kù)/數(shù)據(jù)訪問(wèn)層負(fù)責(zé)與所使用的數(shù)據(jù)的存儲(chǔ)進(jìn)行通信。

分離關(guān)注(Soc)是分離計(jì)算機(jī)程序?yàn)椴煌牟糠?#xff0c;每個(gè)部分有一個(gè)關(guān)注聚焦,一個(gè)典型的Spring Web應(yīng)用在一定程度上遵循這一原則,但現(xiàn)實(shí)是,該應(yīng)用程序有一個(gè)整體的服務(wù)層,它有太多的責(zé)任。更具體地,服務(wù)層有兩個(gè)主要問(wèn)題:

  1.在服務(wù)層發(fā)現(xiàn)業(yè)務(wù)邏輯。業(yè)務(wù)邏輯被分散在各個(gè)服務(wù)層。如果我們需要檢查一個(gè)業(yè)務(wù)規(guī)則是如何實(shí)現(xiàn)的,我們必須先找到它。這可能并不容易。此外,如果相同的業(yè)務(wù)規(guī)則需要在多個(gè)服務(wù)類,問(wèn)題是,規(guī)則需要從一個(gè)服務(wù)到另一個(gè)簡(jiǎn)單地復(fù)制。這將導(dǎo)致維護(hù)的噩夢(mèng)。

  2.每個(gè)領(lǐng)域模型一個(gè)服務(wù)。這完全違反了單一職責(zé)原則,它被定義為如下:單一職責(zé)原則指出,每一個(gè)類都應(yīng)該有一個(gè)責(zé)任,責(zé)任應(yīng)該由類完全封裝。其所有的服務(wù)應(yīng)該狹義與責(zé)任相一致。(不應(yīng)將原屬于領(lǐng)域模型的行為方法等劃放在服務(wù)中實(shí)現(xiàn),對(duì)象不但有屬性還有行為)。

服務(wù)類有很多依賴,以及大量的循環(huán)依賴。更像網(wǎng)絡(luò)緊密耦合和單片服務(wù)。這使得很難理解,維護(hù)和重用。這聽(tīng)起來(lái)有點(diǎn)苛刻,但一個(gè)Spring的web應(yīng)用的服務(wù)層往往是最容易出問(wèn)題的部分。幸運(yùn)的是,所有的希望都不會(huì)丟失。

1. 我們必須將我們的應(yīng)用程序的業(yè)務(wù)邏輯從服務(wù)層遷移到領(lǐng)域模型類中。

舉個(gè)例子:假設(shè)我是一個(gè)服務(wù)類,你是一個(gè)域模型對(duì)象。如果我讓你從屋頂上跳下來(lái),你會(huì)喜歡我這樣的決定嗎?(跳下來(lái)會(huì)摔傷,自己沒(méi)有腦子或被洗腦,變成僵尸,只聽(tīng)從執(zhí)行,不思考自己的安全,這就是貧血模型的問(wèn)題)

將業(yè)務(wù)邏輯從服務(wù)層遷移到域模型類有下面三個(gè)優(yōu)勢(shì):

(1)我們的代碼將以邏輯方式切割,服務(wù)層只要關(guān)注應(yīng)用邏輯,而我們的領(lǐng)域模型關(guān)注業(yè)務(wù)邏輯。
(2)業(yè)務(wù)邏輯只存在一個(gè)地方,容易發(fā)現(xiàn)修改。
(3)服務(wù)層的源代碼是清潔的,不包含任何復(fù)制粘貼代碼

2. 將每個(gè)實(shí)體服務(wù)切割為單一目標(biāo)的更小的服務(wù)。

比如,有一個(gè)單一服務(wù)類,提供對(duì)人員和用戶賬戶的CRUD操作,我們應(yīng)該將它分為兩個(gè)獨(dú)立的服務(wù)類:
第一個(gè)是對(duì)人員的提供CRUD操作
第二個(gè)是提供與用戶賬戶相關(guān)的操作。

好處:每個(gè)服務(wù)類中有一個(gè)邏輯組職責(zé)。每個(gè)服務(wù)類的依賴較少,這意味著他們不再是緊耦合的源頭。他們是較小的和松耦合的組件。服務(wù)類更容易理解,維護(hù)和重用。

這兩個(gè)簡(jiǎn)單的步驟將幫助我們使得我們的應(yīng)用程序架構(gòu)更干凈,有助于同行開(kāi)發(fā)商提高生產(chǎn)力和幸福。

第四篇 日志

日志是一種簡(jiǎn)單的不能再簡(jiǎn)單的存儲(chǔ)抽象。它是一個(gè)只能增加的(?append),完全按照時(shí)間排序的一系列記錄。日志看起來(lái)如下:

?

只能給日志的末尾添加記錄(append 類似隊(duì)列),日志記錄是從左到右讀取的。每一條日志記錄都有一個(gè)唯一的序列編號(hào)(一般我們使用時(shí)間戳)。?日志記錄的排序是由"時(shí)間"決定,處于左邊的記錄比右邊的要早些。記錄編號(hào)可以看作是這條記錄的"時(shí)間戳"。當(dāng)然剛開(kāi)始我們就把這種排序說(shuō)成是按時(shí)間排序顯得有點(diǎn)多余,不過(guò),與任何一個(gè)具體的物理時(shí)鐘相比,時(shí)間屬性是非常便于使用的屬性。在多個(gè)分布式系統(tǒng)中,時(shí)間會(huì)非常重要。?日志在存儲(chǔ)空間完全耗盡的情況下,就不可能再給日志添加記錄。稍后我們將會(huì)提到這個(gè)問(wèn)題。?日志只是按照時(shí)間順序存儲(chǔ)記錄的?一種數(shù)據(jù)表或者文件,可以表現(xiàn)為日志文件或日志數(shù)據(jù)庫(kù)。日志重要特點(diǎn)是:它記錄了在某個(gè)什么時(shí)間發(fā)生了什么事情。 而這對(duì)分布式數(shù)據(jù)系統(tǒng)而言才是問(wèn)題的真正核心。不過(guò),在我們更加深入的討論之前,先澄清有些讓人混淆的概念。每個(gè)編程人員都熟悉另一種日志:使用syslog或者log4j寫(xiě)入到本地文件里的、沒(méi)有結(jié)構(gòu)的、跟蹤信息或錯(cuò)誤信息。為了將兩者區(qū)分開(kāi)來(lái),我們把這種日志稱為"應(yīng)用日志"。應(yīng)用日志是我所說(shuō)日志中的一種低級(jí)變種。兩者最大的區(qū)別是:這些文本日志意味著主要用來(lái)方便人們閱讀,而我所說(shuō)的"日志"或者"數(shù)據(jù)日志"是為了方便程序訪問(wèn)。(實(shí)際上,如果你對(duì)它進(jìn)行深入的思考,那么人們自己讀取某個(gè)機(jī)器上的日志這種理念有些不順應(yīng)時(shí)代潮流。當(dāng)涉及到許多服務(wù)和服務(wù)器的時(shí)候,這種方法很快就變成一個(gè)難于管理的。)

數(shù)據(jù)庫(kù)日志:日志在數(shù)據(jù)庫(kù)里的用法是:當(dāng)數(shù)據(jù)庫(kù)崩潰的時(shí)候用日志來(lái)同步各種數(shù)據(jù)結(jié)構(gòu)和索引。為了保證操作的原子性和持久性,在對(duì)數(shù)據(jù)庫(kù)進(jìn)行維護(hù),也就是所有各種數(shù)據(jù)結(jié)構(gòu)做出更改之前,數(shù)據(jù)庫(kù)會(huì)把即將修改的信息備份追加到日志里。日志記錄了已經(jīng)發(fā)生了什么,每個(gè)表或者索引都是其歷史投影。由于日志是即刻持久化的,所以在宕機(jī)時(shí)可以用來(lái)作為恢復(fù)的可信數(shù)據(jù)源。

隨著時(shí)間推移,日志用途從實(shí)現(xiàn)ACID發(fā)展為數(shù)據(jù)庫(kù)之間復(fù)制數(shù)據(jù)的一種方法。發(fā)生在數(shù)據(jù)庫(kù)上的操作動(dòng)作順序與遠(yuǎn)端備份數(shù)據(jù)庫(kù)上的操作順序通過(guò)日志保持完全同步。Oracle,MySQL 和PostgreSQL都是使用復(fù)制日志同步實(shí)現(xiàn)主從同步。Oracle還把日志產(chǎn)品化為一個(gè)通用的數(shù)據(jù)訂閱機(jī)制,MySQL和PostgreSQL有類似的實(shí)現(xiàn)則,日志已經(jīng)成為許多數(shù)據(jù)結(jié)構(gòu)的關(guān)鍵組件。正是由于這樣的起源,機(jī)器可識(shí)別的日志這個(gè)概念大部分時(shí)候還是都被局限在數(shù)據(jù)庫(kù)內(nèi)部。日志用做數(shù)據(jù)訂閱的機(jī)制似乎是偶然出現(xiàn),不過(guò)要把這種數(shù)據(jù)抽象用于支持所有類型的消息傳輸、數(shù)據(jù)流和實(shí)時(shí)數(shù)據(jù)處理也是可行的。

分布式系統(tǒng)日志:日志解決了兩個(gè)問(wèn)題:操作動(dòng)作的順序化和數(shù)據(jù)的分發(fā),這兩個(gè)問(wèn)題在分布式數(shù)據(jù)系統(tǒng)里顯得尤為重要。保持一致的操作動(dòng)作的順序是分布式系統(tǒng)設(shè)計(jì)的核心問(wèn)題之一。以日志為中心實(shí)現(xiàn)分布式系統(tǒng)是受到了一個(gè)簡(jiǎn)單經(jīng)驗(yàn)常識(shí)的啟發(fā),它稱為狀態(tài)機(jī)復(fù)制原理:如果兩個(gè)相同的確定的處理過(guò)程從同一狀態(tài)開(kāi)始,以相同的順序輸入相同的(數(shù)據(jù)或事件),那么這兩個(gè)處理過(guò)程必然會(huì)產(chǎn)生相同的輸出(結(jié)果),并且在最后相同的狀態(tài)結(jié)束。這也許有點(diǎn)難以理解,讓我們更加深入的探討,弄懂它的真正含義。確定性意味著處理過(guò)程是與時(shí)間無(wú)關(guān),而且任何其他"外部的"輸入不會(huì)影響到其處理結(jié)果。例如,如果一個(gè)程序的輸出會(huì)受到線程執(zhí)行的具體順序影響,或者受到getTimeOfDay調(diào)用、或者其他一些非重復(fù)性事件的影響,那么這樣的程序一般被認(rèn)為是非確定性的。處理狀態(tài)是處理過(guò)程保存在計(jì)算機(jī)上的任何數(shù)據(jù)(狀態(tài)),在處理過(guò)程結(jié)束后,這些狀態(tài)數(shù)據(jù)要么保存在內(nèi)存里,要么保存在磁盤(pán)上。“以相同的順序獲得相同輸入”這個(gè)地方應(yīng)當(dāng)引起注意的是:這里就是引入日志的地方。這兒有一個(gè)重要的常識(shí):如果給兩段確定性代碼相同的日志輸入,那么它們就會(huì)生成相同的輸出。分布式計(jì)算在這方面的應(yīng)用格外明顯。你可以把用多臺(tái)機(jī)器一起執(zhí)行同一件事情縮減為為這些進(jìn)程輸入分布式一致性的日志數(shù)據(jù)。這里使用日志的目的是把所有非確定性的東西排除在輸入流之外,這樣來(lái)確保每個(gè)復(fù)制都能夠同步地處理輸入。當(dāng)你理解了以后,狀態(tài)機(jī)復(fù)制原理就不再?gòu)?fù)雜或者說(shuō)不再深?yuàn)W了:它或多或少的意味著"確定性的處理過(guò)程就是確定性的"。不管怎樣,我都認(rèn)為它是分布式系統(tǒng)設(shè)計(jì)里較常用的設(shè)計(jì)工具之一。這種方式的一個(gè)美妙之處就在于作為日志的索引的時(shí)間戳就像時(shí)鐘狀態(tài)的一個(gè)副本。你可以用一個(gè)單獨(dú)的數(shù)字描述每一個(gè)副本,這就是經(jīng)過(guò)處理的日志的時(shí)間戳。時(shí)間戳與日志一一對(duì)應(yīng)著整個(gè)副本的狀態(tài)。由于寫(xiě)進(jìn)日志的內(nèi)容不同,也就會(huì)有許多在系統(tǒng)中應(yīng)用這個(gè)原則的不同方式。舉個(gè)例子,我們可以記錄一個(gè)服務(wù)的請(qǐng)求,或者也可以記錄服務(wù)從請(qǐng)求到響應(yīng)的狀態(tài)變化,或者它執(zhí)行命令的轉(zhuǎn)換。理論上來(lái)說(shuō),我們甚至可以為每一個(gè)要執(zhí)行的機(jī)器指令或者調(diào)用的方法名和參數(shù)實(shí)現(xiàn)一系列副本記錄。只要兩個(gè)處理過(guò)程用相同的方式處理這些輸入,這些處理過(guò)程就會(huì)保持副本的一致性。一千個(gè)人眼中有一千種日志的用法。數(shù)據(jù)庫(kù)工作者通常區(qū)分物理日志和邏輯日志。物理日志就是記錄每一行被改變的內(nèi)容。邏輯日志記錄的不是改變的行,而是那些引起行的內(nèi)容被改變的SQL語(yǔ)句(insert,update和delete語(yǔ)句)。分布式系統(tǒng)通常可以寬泛劃分為兩種方法來(lái)進(jìn)行數(shù)據(jù)處理和復(fù)制。"狀態(tài)機(jī)器模型"通常使用一個(gè)active-active模型,在這個(gè)模型中我們保存了請(qǐng)求和該請(qǐng)求的復(fù)制處理。我們可以對(duì)"狀態(tài)機(jī)器模型"進(jìn)行細(xì)微的更改,稱之為"預(yù)備份primary-backup模型",也就是選出一個(gè)副本做為leader,并允許它按照請(qǐng)求到達(dá)的時(shí)間來(lái)進(jìn)行處理請(qǐng)求,并將該請(qǐng)求導(dǎo)致?tīng)顟B(tài)的改變輸出到日志。其他的副本按照l(shuí)eader狀態(tài)改變的順序而應(yīng)用執(zhí)行這些改變,這樣他們之間就能達(dá)到同步,并能夠在leader失敗的時(shí)候接替leader的工作。

第五篇 HTTP 2.0說(shuō)明

  今年春節(jié)的時(shí)候,我們發(fā)現(xiàn)之前訪問(wèn)www.baidu.com會(huì)跳轉(zhuǎn)到http://www.baidu.com。但是從這天起,訪問(wèn)都跳轉(zhuǎn)到了https://www.baidu.com。http是基于http1.0協(xié)議的。https是基于http2.0協(xié)議的。使用了https之后,我們看看發(fā)生了些什么變化。

  百度實(shí)現(xiàn)全站https這一技術(shù)的實(shí)現(xiàn),有效避免網(wǎng)絡(luò)信息劫持。百度這次的全站https就是一種加密協(xié)議,即使在傳輸?shù)倪^(guò)程中被截取,也是加密的形式,所以被截取的信息都是無(wú)用的數(shù)據(jù)。

?

百度的這次全站https以后發(fā)展下來(lái),是不是百度要對(duì)收錄的網(wǎng)站進(jìn)行更高的安全級(jí)別。當(dāng)使用http的時(shí)候,你訪問(wèn)網(wǎng)站的所有數(shù)據(jù)都是明文的,只要中間有人抓到數(shù)據(jù)包就能知道你要搜索的東西。換成https的,至少別人抓到你的數(shù)據(jù)包也不知道你搜索的是啥。(https起到了保護(hù)隱私的作用)
  那么在性能方面:https多幾次握手,網(wǎng)絡(luò)耗時(shí)變長(zhǎng),用戶從http跳轉(zhuǎn)到https還要一點(diǎn)時(shí)間。機(jī)器性能:機(jī)器性能,https要多做一次RSA校驗(yàn)。CDN:全國(guó)所有節(jié)點(diǎn)要支持https才行,另外,如果面對(duì)DDOS,https的解決方案也會(huì)復(fù)雜得多。

  對(duì)周邊系統(tǒng)的影響:頁(yè)面里所有嵌入的資源都要改成https的,這些資源可能會(huì)來(lái)自不同的部門(mén)甚至不同的公司,包括:圖片、js、form表單等等,否則瀏覽器就會(huì)報(bào)警。手機(jī)百度這類使用了百度搜索服務(wù)的客戶端產(chǎn)品,也可能要修改。解決第三方網(wǎng)站看不到refer的問(wèn)題。所有的開(kāi)發(fā)、測(cè)試環(huán)境都要做https的升級(jí)。
  使用https的收益:?最惡心的是泄露用戶數(shù)據(jù),經(jīng)常在網(wǎng)上看到說(shuō)「我用百度搜了一個(gè)黃金,馬上就有人聯(lián)系我了」「我在百度上搜了一種病,馬上醫(yī)院就來(lái)電話了」。其實(shí)在搜索HTTPS很久之前,百度就做了搜索結(jié)果url加密。用戶搜索安全,被運(yùn)營(yíng)商強(qiáng)插廣告,甚至在正常結(jié)果前面插一條廣告。?

?

?

總結(jié)

以上是生活随笔為你收集整理的Spring web应用最大的败笔的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。