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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > linux >内容正文

linux

osgi架构与linux_OSGi:进入微服务架构的门户

發(fā)布時(shí)間:2023/12/3 linux 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 osgi架构与linux_OSGi:进入微服务架构的门户 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

osgi架構(gòu)與linux

在構(gòu)建可擴(kuò)展,可靠的分布式系統(tǒng)的背景下,“模塊化”和“微服務(wù)體系結(jié)構(gòu)”這兩個(gè)術(shù)語(yǔ)如今經(jīng)常出現(xiàn)。 眾所周知,Java平臺(tái)本身在模塊化方面很弱( Java 9將通過交付Jigsaw項(xiàng)目來(lái)解決此問題),這為OSGi和JBoss Modules等框架的出現(xiàn)提供了機(jī)會(huì)。

當(dāng)我在2007年第一次聽說(shuō)OSGi時(shí) ,我真的很高興Java應(yīng)用程序可以在其之上構(gòu)建而受益。 但是很快就產(chǎn)生了挫敗感,而不是興奮感:沒有工具支持,兼容的庫(kù)和框架非常有限,非常不穩(wěn)定,難以對(duì)運(yùn)行時(shí)進(jìn)行故障排除。 顯然,普通的Java開發(fā)人員還沒有準(zhǔn)備好使用它,因此,我不得不把它放在架子上。 多年來(lái), OSGi已經(jīng)成熟很多,并得到了廣泛的社區(qū)支持。

好奇的讀者可能會(huì)問:特別是使用模塊和OSGi有什么好處? 僅舉幾個(gè)問題,它有助于解決:

  • 顯式(和版本控制)依賴關(guān)系管理:模塊聲明所需的內(nèi)容(以及可選的版本范圍)
  • 占用空間小:模塊未包裝所有依賴項(xiàng)
  • 易于發(fā)布:模塊可以獨(dú)立開發(fā)和發(fā)布
  • 熱部署:可以在不影響其他模塊的情況下重新部署各個(gè)模塊

在今天的帖子中,我們將對(duì)使用OSGi構(gòu)建模塊化Java應(yīng)用程序的最新技術(shù)水平進(jìn)行10000英尺的考察。 撇開OSGi的好壞進(jìn)行討論,我們將構(gòu)建一個(gè)包含以下模塊的示例應(yīng)用程序:

  • 數(shù)據(jù)訪問模塊
  • 商業(yè)服務(wù)模塊
  • REST服務(wù)模塊

用于數(shù)據(jù)訪問的Apache OpenJPA 2.3.0 / JPA 2.0 (不幸的是,我們選擇的OSGi實(shí)現(xiàn)尚未支持JPA 2.1 ),用于REST層的Apache CXF 3.0.1 / JAX-RS 2.0是應(yīng)用程序的兩個(gè)主要構(gòu)建塊。 我發(fā)現(xiàn)Christian Schneider的博客Liquid Reality是有關(guān)OSGi (以及許多其他主題)的寶貴信息來(lái)源。

在OSGi世界中,這些模塊稱為bundles 。 捆綁包顯示了它們的依賴關(guān)系(導(dǎo)入包)和它們公開的包(導(dǎo)出包),因此其他捆綁包可以使用它們。 Apache Maven也支持此打包模型。 捆綁包由OSGi運(yùn)行時(shí)或容器管理,在我們的情況下將是Apache Karaf 3.0.1 (實(shí)際上,這是我們需要下載 和解壓縮的內(nèi)容)。

讓我停止說(shuō)話,更好地顯示一些代碼。 我們將從頂部( REST )開始,一直到底部(數(shù)據(jù)訪問),因?yàn)樗菀鬃裱?我們的PeopleRestService是JAX-RS 2.0服務(wù)實(shí)現(xiàn)的典型示例:

package com.example.jaxrs;import java.util.Collection;import javax.ws.rs.DELETE; import javax.ws.rs.DefaultValue; import javax.ws.rs.FormParam; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo;import com.example.data.model.Person; import com.example.services.PeopleService;@Path( "/people" ) public class PeopleRestService {private PeopleService peopleService;@Produces( { MediaType.APPLICATION_JSON } )@GETpublic Collection< Person > getPeople( @QueryParam( "page") @DefaultValue( "1" ) final int page ) {return peopleService.getPeople( page, 5 );}@Produces( { MediaType.APPLICATION_JSON } )@Path( "/{email}" )@GETpublic Person getPerson( @PathParam( "email" ) final String email ) {return peopleService.getByEmail( email );}@Produces( { MediaType.APPLICATION_JSON } )@POSTpublic Response addPerson( @Context final UriInfo uriInfo,@FormParam( "email" ) final String email, @FormParam( "firstName" ) final String firstName, @FormParam( "lastName" ) final String lastName ) {peopleService.addPerson( email, firstName, lastName );return Response.created( uriInfo.getRequestUriBuilder().path( email ).build() ).build();}@Produces( { MediaType.APPLICATION_JSON } )@Path( "/{email}" )@PUTpublic Person updatePerson( @PathParam( "email" ) final String email, @FormParam( "firstName" ) final String firstName, @FormParam( "lastName" ) final String lastName ) {final Person person = peopleService.getByEmail( email );if( firstName != null ) {person.setFirstName( firstName );}if( lastName != null ) {person.setLastName( lastName );}return person; }@Path( "/{email}" )@DELETEpublic Response deletePerson( @PathParam( "email" ) final String email ) {peopleService.removePerson( email );return Response.ok().build();}public void setPeopleService( final PeopleService peopleService ) {this.peopleService = peopleService;} }

我們可以看到,這里沒有任何關(guān)于OSGi的信息 。 唯一的依賴是在某種程度上應(yīng)該被注入PeopleRestService的PeopleService。 怎么樣? 通常, OSGi應(yīng)用程序使用藍(lán)圖作為依賴項(xiàng)注入框架,這與基于XML的老伙伴Spring配置非常相似。 它應(yīng)該與應(yīng)用程序一起打包在OSGI-INF / blueprint文件夾中。 這是在Apache CXF 3.0.1之上構(gòu)建的REST模塊的藍(lán)圖示例:

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:jaxrs="http://cxf.apache.org/blueprint/jaxrs"xmlns:cxf="http://cxf.apache.org/blueprint/core"xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsdhttp://cxf.apache.org/blueprint/jaxws http://cxf.apache.org/schemas/blueprint/jaxws.xsdhttp://cxf.apache.org/blueprint/jaxrs http://cxf.apache.org/schemas/blueprint/jaxrs.xsdhttp://cxf.apache.org/blueprint/core http://cxf.apache.org/schemas/blueprint/core.xsd"><cxf:bus id="bus"><cxf:features><cxf:logging/></cxf:features> </cxf:bus><jaxrs:server address="/api" id="api"><jaxrs:serviceBeans><ref component-id="peopleRestService"/></jaxrs:serviceBeans><jaxrs:providers><bean class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider" /></jaxrs:providers></jaxrs:server><!-- Implementation of the rest service --><bean id="peopleRestService" class="com.example.jaxrs.PeopleRestService"><property name="peopleService" ref="peopleService"/></bean> <reference id="peopleService" interface="com.example.services.PeopleService" /> </blueprint>

非常小而簡(jiǎn)單:基本上,配置僅指出為了使模塊正常工作,應(yīng)提供對(duì)com.example.services.PeopleService的引用(有效地由OSGi容器提供)。 為了了解它是如何發(fā)生的,讓我們看一下另一個(gè)公開服務(wù)的模塊。 它僅包含一個(gè)接口PeopleService :

package com.example.services;import java.util.Collection;import com.example.data.model.Person;public interface PeopleService {Collection< Person > getPeople( int page, int pageSize );Person getByEmail( final String email );Person addPerson( final String email, final String firstName, final String lastName );void removePerson( final String email ); }

并提供其實(shí)現(xiàn)作為PeopleServiceImpl類:

package com.example.services.impl;import java.util.Collection;import org.osgi.service.log.LogService;import com.example.data.PeopleDao; import com.example.data.model.Person; import com.example.services.PeopleService;public class PeopleServiceImpl implements PeopleService {private PeopleDao peopleDao;private LogService logService;@Overridepublic Collection< Person > getPeople( final int page, final int pageSize ) { logService.log( LogService.LOG_INFO, "Getting all people" );return peopleDao.findAll( page, pageSize );}@Overridepublic Person getByEmail( final String email ) {logService.log( LogService.LOG_INFO, "Looking for a person with e-mail: " + email );return peopleDao.find( email ); }@Overridepublic Person addPerson( final String email, final String firstName, final String lastName ) {logService.log( LogService.LOG_INFO, "Adding new person with e-mail: " + email );return peopleDao.save( new Person( email, firstName, lastName ) );}@Overridepublic void removePerson( final String email ) {logService.log( LogService.LOG_INFO, "Removing a person with e-mail: " + email );peopleDao.delete( email );}public void setPeopleDao( final PeopleDao peopleDao ) {this.peopleDao = peopleDao;}public void setLogService( final LogService logService ) {this.logService = logService;} }

這次又一次是非常小的,干凈的實(shí)現(xiàn),它具有兩個(gè)可注入的依賴項(xiàng)org.osgi.service.log.LogService和com.example.data.PeopleDao 。 它的藍(lán)圖配置位于OSGI-INF / blueprint文件夾中,看起來(lái)也很緊湊:

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"><service ref="peopleService" interface="com.example.services.PeopleService" /> <bean id="peopleService" class="com.example.services.impl.PeopleServiceImpl"><property name="peopleDao" ref="peopleDao" /> <property name="logService" ref="logService" /></bean><reference id="peopleDao" interface="com.example.data.PeopleDao" /><reference id="logService" interface="org.osgi.service.log.LogService" /> </blueprint>

預(yù)期由OSGi容器在運(yùn)行時(shí)提供對(duì)PeopleDao和LogService的引用。 但是, PeopleService的實(shí)現(xiàn)是作為服務(wù)公開的,并且一旦其捆綁包被激活, OSGi容器將能夠?qū)⑵渥⑷隤eopleRestService 。

難題的最后一部分,數(shù)據(jù)訪問模塊,稍微復(fù)雜一點(diǎn):它包含持久性配置( META-INF / persistence.xml ),并且基本上依賴于OSGi容器的JPA 2.0功能。 persistence.xml非常基本:

<persistence xmlns="http://java.sun.com/xml/ns/persistence"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"version="2.0"><persistence-unit name="peopleDb" transaction-type="JTA"><jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=peopleDb)</jta-data-source> <class>com.example.data.model.Person</class><properties><property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema"/> </properties> </persistence-unit> </persistence>

與服務(wù)模塊類似, PeopleDao公開了一個(gè)接口:

package com.example.data;import java.util.Collection;import com.example.data.model.Person;public interface PeopleDao {Person save( final Person person );Person find( final String email );Collection< Person > findAll( final int page, final int pageSize );void delete( final String email ); }

通過其實(shí)現(xiàn)PeopleDaoImpl :

package com.example.data.impl;import java.util.Collection;import javax.persistence.EntityManager; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery;import com.example.data.PeopleDao; import com.example.data.model.Person;public class PeopleDaoImpl implements PeopleDao {private EntityManager entityManager;@Overridepublic Person save( final Person person ) {entityManager.persist( person );return person;}@Overridepublic Person find( final String email ) {return entityManager.find( Person.class, email );}public void setEntityManager( final EntityManager entityManager ) {this.entityManager = entityManager;}@Overridepublic Collection< Person > findAll( final int page, final int pageSize ) {final CriteriaBuilder cb = entityManager.getCriteriaBuilder();final CriteriaQuery< Person > query = cb.createQuery( Person.class );query.from( Person.class );return entityManager.createQuery( query ).setFirstResult(( page - 1 ) * pageSize ).setMaxResults( pageSize ) .getResultList();}@Overridepublic void delete( final String email ) {entityManager.remove( find( email ) );} }

請(qǐng)注意,盡管我們正在執(zhí)行數(shù)據(jù)操作,但是沒有提及事務(wù),也沒有對(duì)實(shí)體管理器的事務(wù)API的顯式調(diào)用。 我們將使用聲明式方法進(jìn)行事務(wù)處理,因?yàn)樗{(lán)圖配置支持(位置不變, OSGI-INF / blueprint文件夾):

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:jpa="http://aries.apache.org/xmlns/jpa/v1.1.0"xmlns:tx="http://aries.apache.org/xmlns/transactions/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"><service ref="peopleDao" interface="com.example.data.PeopleDao" /><bean id="peopleDao" class="com.example.data.impl.PeopleDaoImpl"><jpa:context unitname="peopleDb" property="entityManager" /><tx:transaction method="*" value="Required"/></bean><bean id="dataSource" class="org.hsqldb.jdbc.JDBCDataSource"><property name="url" value="jdbc:hsqldb:mem:peopleDb"/></bean><service ref="dataSource" interface="javax.sql.DataSource"> <service-properties> <entry key="osgi.jndi.service.name" value="peopleDb" /> </service-properties> </service> </blueprint>

要記住的一件事:應(yīng)用程序不需要?jiǎng)?chuàng)建JPA 2.1的實(shí)體管理器: OSGi運(yùn)行時(shí)能夠做到這一點(diǎn),并將其注入到需要的地方,由jpa:context聲明驅(qū)動(dòng)。 因此, tx:transaction指示運(yùn)行時(shí)將選定的服務(wù)方法包裝在事務(wù)中。

現(xiàn)在,當(dāng)提供最后一個(gè)服務(wù)PeopleDao時(shí) ,我們準(zhǔn)備使用Apache Karaf 3.0.1部署我們的模塊。 三個(gè)步驟很容易做到:

  • 運(yùn)行Apache Karaf 3.0.1容器 bin/karaf (or bin\karaf.bat on Windows)
  • 從Apache Karaf 3.0.1 shell執(zhí)行以下命令: feature:repo-add cxf 3.0.1 feature:install http cxf jpa openjpa transaction jndi jdbc install -s mvn:org.hsqldb/hsqldb/2.3.2 install -s mvn:com.fasterxml.jackson.core/jackson-core/2.4.0 install -s mvn:com.fasterxml.jackson.core/jackson-annotations/2.4.0 install -s mvn:com.fasterxml.jackson.core/jackson-databind/2.4.0 install -s mvn:com.fasterxml.jackson.jaxrs/jackson-jaxrs-base/2.4.0 install -s mvn:com.fasterxml.jackson.jaxrs/jackson-jaxrs-json-provider/2.4.0
  • 構(gòu)建我們的模塊并將其復(fù)制到Apache Karaf 3.0.1的deploy文件夾(容器仍在運(yùn)行時(shí)): mvn clean package cp module*/target/*jar apache-karaf-3.0.1/deploy/

在Apache Karaf 3.0.1 Shell中運(yùn)行l(wèi)ist命令時(shí),應(yīng)該看到所有激活的捆綁軟件(模塊)的列表,類似于以下列表:


其中module-service , module-jax-rs和module-data對(duì)應(yīng)于我們正在開發(fā)的模塊。 默認(rèn)情況下,我們所有的Apache CXF 3.0.1服務(wù)將在基本URL http:// :8181 / cxf / api /上提供。 通過在Apache Karaf 3.0.1 shell中執(zhí)行cxf:list-endpoints -f命令很容易檢查。

讓我們通過發(fā)送幾個(gè)HTTP請(qǐng)求來(lái)確保REST層按預(yù)期工作。 讓我們創(chuàng)建一個(gè)新人:

curl http://localhost:8181/cxf/api/people -iX POST -d "firstName=Tom&lastName=Knocker&email=a@b.com"HTTP/1.1 201 Created Content-Length: 0 Date: Sat, 09 Aug 2014 15:26:17 GMT Location: http://localhost:8181/cxf/api/people/a@b.com Server: Jetty(8.1.14.v20131031)

并驗(yàn)證此人已成功創(chuàng)建:

curl -i http://localhost:8181/cxf/api/peopleHTTP/1.1 200 OK Content-Type: application/json Date: Sat, 09 Aug 2014 15:28:20 GMT Transfer-Encoding: chunked Server: Jetty(8.1.14.v20131031)[{"email":"a@b.com","firstName":"Tom","lastName":"Knocker"}]

檢查數(shù)據(jù)庫(kù)是否也有人填充會(huì)很好。 使用Apache Karaf 3.0.1 shell,只需執(zhí)行兩個(gè)命令即可輕松完成: jdbc:datasources和jdbc:query peopleDb“ select * from people” 。

太棒了! 我希望這篇介紹性很強(qiáng)的博客文章能打開另一篇有趣的技術(shù),您可以將其用于開發(fā)健壯,可伸縮,模塊化和可管理的軟件。 我們沒有涉及很多東西,但是您可以在這里找到它們。 完整的源代碼可在GitHub上找到 。

Hibernate 4.2.x / 4.3.x用戶注意:不幸的是,在當(dāng)前版本的Apache Karaf 3.0.1中 , Hibernate 4.3.x完全可以正常工作(因?yàn)樯胁恢С諮PA 2.1 ),但是我設(shè)法做到了與Hibernate 4.2.x一起運(yùn)行時(shí),容器通常拒絕解析與JPA相關(guān)的依賴關(guān)系。

翻譯自: https://www.javacodegeeks.com/2014/08/osgi-the-gateway-into-micro-services-architecture.html

osgi架構(gòu)與linux

總結(jié)

以上是生活随笔為你收集整理的osgi架构与linux_OSGi:进入微服务架构的门户的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

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