Microser­vices are get­ting more and more atten­tion and com­pa­nies often con­sid­er them as the solu­tion to reach agili­ty and faster time to mar­ket. How­ev­er, in many of the dis­cus­sions there is a lot of con­fu­sion and lack of under­stand­ing the basic prin­ci­ples of microser­vices. Most impor­tant­ly, one  must dis­tin­guish between the style of deploy­ing an appli­ca­tion with the archi­tec­tur­al style of the appli­ca­tion.

The def­i­n­i­tion of microser­vices the indus­try has agreed on goes back to James Lewis and Mar­tin Fowler: “[] the microser­vice archi­tec­tur­al style is an approach to devel­op­ing a sin­gle appli­ca­tion as a suite of small ser­vices, each run­ning in its own process and com­mu­ni­cat­ing with light­weight mech­a­nisms, often an HTTP resource API.” Or in oth­er words you decom­pose your appli­ca­tion into iso­lat­ed ser­vices basi­cal­ly cre­at­ing a ser­vice ori­ent­ed archi­tec­ture. In this sense a microser­vice is a unit offer­ing ser­vices and poten­tial­ly using oth­er ser­vices. Leav­ing the deploy­ment and com­mu­ni­ca­tion aside, a microser­vice is an iso­lat­ed mod­ule that com­mu­ni­cates with oth­er modules/microservices through ser­vice APIs.

The essence of microser­vices is mod­u­lar­i­ty. But devel­op­ing microser­vices is not the only way to use mod­ules for build­ing appli­ca­tions. While microser­vices give you iso­la­tion through iso­lat­ed deploy­ments, oth­er tech­nolo­gies exist allow­ing you to assem­ble an appli­ca­tion out of iso­lat­ed mod­ules run­ning inside a sin­gle process. The most famous tech­nol­o­gy for this is OSGi, the Dynam­ic Mod­ule Sys­tem for Java. It allows to devel­op inde­pen­dent mod­ules declar­ing their require­ments and capa­bil­i­ties. The capa­bil­i­ties are usu­al­ly ser­vices used by oth­er mod­ules and the require­ments are exact­ly the ser­vices a mod­ule uses from oth­er mod­ules. OSGi pro­vides you an in-process ser­vice ori­ent­ed approach with clear iso­la­tion between the mod­ules. Such an approach is usu­al­ly referred to as a mod­u­lar appli­ca­tion. This is in con­trast to a mono­lith­ic appli­ca­tion where there are no clear bound­aries between the dif­fer­ent code parts run­ning with­in the same appli­ca­tion.

The chal­lenge is to cre­ate an appli­ca­tion assem­bled out of inde­pen­dent mod­ules, this is true for a mod­u­lar appli­ca­tion as well as for a microser­vices based solu­tion. Only by cre­at­ing cohe­sive mod­ules, you will suc­ceed in devel­op­ing a microser­vice based solu­tion. Inter­est­ing­ly, the field is report­ing that very often approach­es to cre­ate a microser­vice based solu­tion on a green field fails. In con­trast approach­es where a mod­u­lar appli­ca­tion is used as a start­ing point and after­wards even­tu­al­ly trans­formed into microser­vices has a much high­er chance of suc­cess. The advan­tage of start­ing with a mod­u­lar appli­ca­tion is reduced com­plex­i­ty in con­trast to start­ing with microser­vices direct­ly.

It seems that often peo­ple who advo­cate microser­vices claim that every­thing else which is not using microser­vices is mono­lith­ic by nature. How­ev­er, this is con­fus­ing the archi­tec­tur­al style of an appli­ca­tion (mod­u­lar vs mono­lith) with the style of deploy­ment. With tech­nolo­gies like OSGi you have a mod­u­lar appli­ca­tion which is deployed as a sin­gle unit. But clear­ly the appli­ca­tion is not mono­lith­ic. With microser­vices you deploy the parts indi­vid­u­al­ly but apart from that there is no dif­fer­ence to an OSGi appli­ca­tion when it comes to mod­u­lar­i­ty.

An appli­ca­tion deployed as a sin­gle unit can of course be mod­u­lar in its nature. By using OSGi and lever­ag­ing mod­ules and ser­vices as defined by the indus­try stan­dard allows you to build your appli­ca­tion in an archi­tec­tur­al style that is very close to microser­vices. The mod­ules can be devel­oped sep­a­rate­ly by dif­fer­ent teams, each team focus­ing on a spe­cif­ic busi­ness capa­bil­i­ty. The mod­ules are loose­ly cou­pled and only com­mu­ni­cate through OSGi ser­vices. As OSGi is a dynam­ic sys­tem, the mod­ules are designed for fail­ure from the start and must han­dle sit­u­a­tions like a ser­vice being not avail­able or unreach­able. The mod­ules can have com­plete­ly dif­fer­ent devel­op­ment life­cy­cles and can be updat­ed and enhanced inde­pen­dent­ly. As explained above an appli­ca­tion deployed as a sin­gle unit can in fact be mod­u­lar. By using OSGi and lever­ag­ing mod­ules and ser­vices as defined by this indus­try stan­dard allows you to build your appli­ca­tion in an archi­tec­tur­al style that is very close to microser­vices. The mod­ules can be devel­oped sep­a­rate­ly by dif­fer­ent teams, each team focus­ing on a spe­cif­ic busi­ness capa­bil­i­ty. The mod­ules are loose­ly cou­pled and only com­mu­ni­cate through OSGi ser­vices. As OSGi is a dynam­ic sys­tem, the mod­ules are designed for fail­ure from the start and must han­dle sit­u­a­tions like a ser­vice being not avail­able or unreach­able. The mod­ules can have com­plete­ly dif­fer­ent devel­op­ment life­cy­cles and can be updat­ed and enhanced inde­pen­dent­ly.

In fact, the only dif­fer­ences between an OSGi appli­ca­tion and a microser­vice archi­tec­ture are ser­vice com­mu­ni­ca­tion and deploy­ment. With­in an OSGi sup­pli­ca­tion the com­mu­ni­ca­tion between the mod­ules is in process and not remote avoid­ing all the addi­tion­al chal­lenges of net­work com­mu­ni­ca­tion. The automa­tion and orches­tra­tion is way sim­pler and less error prone. Thanks to OSGi you can reduce time to mar­ket, devel­op new fea­tures as new mod­ules and sim­ply deploy them to an exist­ing appli­ca­tion.

That’s why we some­times refer to an OSGi appli­ca­tion as “microser­vices in a box”. You get all the ben­e­fits like strong mod­ule bound­aries and inde­pen­dent deploy­ments but avoid the addi­tion­al costs of dis­tri­b­u­tion and espe­cial­ly oper­a­tional com­plex­i­ty. On the oth­er hand, an often heard argu­ment for microser­vices is bet­ter scal­a­bil­i­ty of indi­vid­ual mod­ules in com­bi­na­tion with improved resource uti­liza­tion. The advan­tage here is that you can inde­pen­dent­ly and dynam­i­cal­ly scale up and down the indi­vid­ual microser­vices based on load. While this is true if you only con­sid­er the microser­vice in iso­la­tion, how­ev­er the oper­a­tional infra­struc­ture and know-how you need to have a suc­cess­ful microser­vice archi­tec­ture scal­ing exact­ly as you need is often over­looked.

In addi­tion, you need to know your bot­tle­necks in advance and design them as sep­a­rate micro­scopes. By using OSGi one can defer this deci­sion about deploy­ment topolo­gies until the need for scal­ing indi­vid­ual mod­ules aris­es. By lever­ag­ing OSGi and ser­vices, you can eas­i­ly move an OSGi ser­vice into a dif­fer­ent process and uti­lize OSGi Remote Ser­vices. The appli­ca­tion code itself does not need to be changed at all, you sim­ple change the way of deploy­ing your appli­ca­tion from a sin­gle deploy­ment to sev­er­al based on your needs. And you can do this split up at any time, even dynam­ic at run-time would be pos­si­ble. With OSGi it is pos­si­ble to defer the deci­sion of your deploy­ment time to a lat­er point of time and you can eas­i­ly adjust.

If you want to get into uti­liz­ing microser­vices the pre­req­ui­site is mod­u­lar­i­ty — there is no short cut here. The best approach of devel­op­ing a mod­u­lar appli­ca­tion is OSGi. We picked OSGi as the base for  Expe­ri­ence Man­ag­er exact­ly for that rea­son: mod­u­lar­i­ty. We can inde­pen­dent­ly devel­op the var­i­ous fea­tures, cre­ate well defined con­tracts between the var­i­ous parts and can post­pone the deci­sion about deploy­ment style and ser­vice com­mu­ni­ca­tion at a lat­er time. This allowed us to scale up devel­op­ment to hun­dreds of devel­op­ers while keep­ing teams inde­pen­dent of oth­ers. Well defined APIs and ser­vice inter­face build the foun­da­tion of Expe­ri­ence Man­ag­er. Thanks to OSGi it is already pos­si­ble to check the con­sis­ten­cy of the mod­ules and inspect its depen­den­cies. This way you can con­trol the cohe­sion of your mod­ules. Seman­tic ver­sion­ing defines rules on how to adjust the ver­sion of your Java API based on the change you make. With the OSGi tool­ing you can already check at build time whether you made an incom­pat­i­ble change and which clients of your mod­ule are affect­ed by the change. In sum­ma­ry mod­u­lar­i­ty, OSGi and the avail­able tool­ing gives us a devel­op­ment style which is equal if not supe­ri­or to the microser­vices devel­op­ment style.

On the oth­er hand, if you want to devel­op a new microser­vice to be used by Expe­ri­ence Man­ag­er or any oth­er OSGi appli­ca­tion, start by defin­ing your Java ser­vice API. Imple­ment the func­tion­al­i­ty and deploy this as a sep­a­rate OSGi based appli­ca­tion includ­ing the required mod­ules. Sim­ply use OSGi remote ser­vices to pub­lish these ser­vices remote­ly. In Expe­ri­ence Man­ag­er or your OSGi appli­ca­tion import the mod­ule con­tain­ing the ser­vice API and use remote ser­vices to make your new ser­vice avail­able. Your code run­ning in Expe­ri­ence Man­ag­er just uses plain Java inter­faces and method calls, but runs as a sep­a­rate process which can be scaled inde­pen­dent­ly. At any point in time you can change your deploy­ment set­up and sim­ply add the imple­men­ta­tion mod­ules direct­ly to Expe­ri­ence Man­ag­er if that pro­vides ben­e­fits.

To recap, microser­vices is about mod­u­lar­i­ty. OSGi is the best tech­nol­o­gy for mod­u­lar­i­ty. Expe­ri­ence Man­ag­er is built using OSGi in a mod­u­lar way. This gives you all the flex­i­bil­i­ty and pre­req­ui­sites for using and pro­vid­ing microser­vices with Expe­ri­ence Man­ag­er.

 

Feature Image: Fro: mtomatito26 via Adobe Stock
0 comments