前言
微服務,顧名思義就是微小的單一的服務程序,單一流程,單一發布,開發和部署都可獨立;
這是我的理解;
但基於web的服務,不管是webservice還是webapi等類似的服務都需要基於iis或者tomcat,
本文介紹重點繞過iis或tomc部署基於http服務明文程序;
所謂明文程序就是源碼發布;當然你也可以不必是源碼發布,這個可以個人需求;
序言
請不要問我為什么不直接使用web現成的架構,進行開發部署,
第一:我的項目有這樣的需求;原本就是一個服務程序,提供socket tcp協議數據服務;並且需要提供socket http協議服務;
第二:梳理自己的知識;
第三:對微服務和webapi概念進行強化和模擬實現;
正文開始
在閱讀這篇文字之前建議優先查看之前文章,比如線程,腳本,socket 服務等;
本文先從java版本開始講解;稍后依然會寫上C#,但是代碼機制都是一樣的;本程序習慣作風,java和C#雙版本共存;
本人代碼風格習慣,:
項目主包下面包含功能塊實現;功能塊里面包含單例管理器,如果需要有腳本接口處理iscript里面包含接口的處理形式
我們優先創建文件IWebApiScript

1 package net.sz.game.test.webapi.iscript; 2 3 import net.sz.game.engine.nio.nettys.http.NioHttpRequest; 4 import net.sz.game.engine.scripts.IBaseScript; 5 6 /** 7 * 8 * <br> 9 * author 失足程序員<br> 10 * blog http://www.cnblogs.com/ty408/<br> 11 * mail 492794628@qq.com<br> 12 * phone 13882122019<br> 13 */ 14 public interface IWebApiScript extends IBaseScript { 15 16 /** 17 * 獲取路由設置。自動注冊版 18 * 19 * @return 20 */ 21 String getRoute(); 22 23 boolean action(String url, NioHttpRequest request); 24 25 }
創建WebApiManager
1 package net.sz.game.test.webapi; 2 3 import java.util.ArrayList; 4 import net.sz.game.engine.nio.nettys.NettyPool; 5 import net.sz.game.engine.nio.nettys.http.NettyHttpServer; 6 import net.sz.game.engine.nio.nettys.http.NioHttpRequest; 7 import net.sz.game.engine.nio.nettys.http.handler.IHttpHandler; 8 import net.sz.game.engine.scripts.IBaseScript; 9 import net.sz.game.engine.scripts.manager.ScriptManager; 10 import net.sz.game.engine.szlog.SzLogger; 11 import net.sz.game.test.webapi.iscript.IWebApiScript; 12 13 /** 14 * 15 * <br> 16 * author 失足程序員<br> 17 * blog http://www.cnblogs.com/ty408/<br> 18 * mail 492794628@qq.com<br> 19 * phone 13882122019<br> 20 */ 21 public class WebApiManager { 22 23 private static SzLogger log = SzLogger.getLogger(); 24 private static final WebApiManager IN_ME = new WebApiManager(); 25 26 public static WebApiManager getInstance() { 27 return IN_ME; 28 } 29 30 public void init() { 31 /*獲取http綁定*/ 32 NettyHttpServer addBindHttpServer = NettyPool.getInstance().addBindHttpServer("127.0.0.1", 9527); 33 34 /*添加黑名單 禁止訪問名單*/ 35 //addBindHttpServer.addBlackIP(""); 36 /*添加白名單 必須包含的訪問*/ 37 //addBindHttpServer.addWhiteIP(""); 38 addBindHttpServer.addHttpBind(new IHttpHandler() {/*使用匿名對象*/ 39 40 @Override 41 public void run(String url, NioHttpRequest request) { 42 /*每次都是獲取最新集合*/ 43 ArrayList<IBaseScript> evts = ScriptManager.getInstance().getBaseScriptEntry().getEvts(IWebApiScript.class.getName()); 44 if (evts != null && !evts.isEmpty()) { 45 for (int i = 0; i < evts.size(); i++) { 46 IWebApiScript iWebApiScript = (IWebApiScript) evts.get(i); 47 /*查找需要處理的明文腳本 webapi 路由*/ 48 if (iWebApiScript.getRoute().equalsIgnoreCase(url)) { 49 /*返回值也行有其他用途*/ 50 boolean action = iWebApiScript.action(url, request); 51 /*跳出循環*/ 52 break; 53 } 54 } 55 } 56 /*回復客戶端請求*/ 57 request.respons(); 58 } 59 }/*處理程序*/, 10/*線程量提高並發處理*/, "*"/*監聽狀態*/); 60 /*socket 使用*/ 61 addBindHttpServer.start(4); 62 } 63 }
當前我們並沒有實現路由注冊,
我們看看效果將會是怎么樣的;
當我們在瀏覽器輸入的時候,不會有任何回復產生;
接下來我們試試明文腳本的路由自動注冊效果來回復請求;
我們新建項目,保持項目路徑一直;
net.sz.game.test.scripts
我們在webapi的腳本目錄下創建index路由監聽
1 package net.sz.game.test.scripts.webapi; 2 3 import net.sz.game.engine.nio.nettys.http.NioHttpRequest; 4 import net.sz.game.engine.szlog.SzLogger; 5 import net.sz.game.test.webapi.iscript.IWebApiScript; 6 7 /** 8 * 9 * <br> 10 * author 失足程序員<br> 11 * blog http://www.cnblogs.com/ty408/<br> 12 * mail 492794628@qq.com<br> 13 * phone 13882122019<br> 14 */ 15 public class IndexScript implements IWebApiScript { 16 17 private static SzLogger log = SzLogger.getLogger(); 18 19 @Override 20 public String getRoute() { 21 return "index"; 22 } 23 24 @Override 25 public boolean action(String url, NioHttpRequest request) { 26 /*添加輸出內容,html數據,json數據,txt數據,xml數據,自己定義就好*/ 27 request.addContent("我是明文webapi自動注冊路由"); 28 return true; 29 } 30 31 }
實現路由自動注冊我們需要在啟動main函數加入腳本初始化函數調用
1 package net.sz.game.test.main; 2 3 import java.util.ArrayList; 4 import net.sz.game.engine.scripts.manager.ScriptManager; 5 import net.sz.game.engine.szlog.SzLogger; 6 import net.sz.game.test.webapi.WebApiManager; 7 8 /** 9 * 10 * <br> 11 * author 失足程序員<br> 12 * mail 492794628@qq.com<br> 13 * phone 13882122019<br> 14 */ 15 public class Test_App_Manager { 16 17 private static SzLogger log = SzLogger.getLogger(); 18 19 public static void main(String[] args) { 20 21 /*加載所有腳本文件,默認加載項目路徑 -scripts 文件下面所有問題*/ 22 ArrayList<String> loadScripts = ScriptManager.getInstance().reload(); 23 String join = String.join(",", loadScripts); 24 log.error(join); 25 /*初始化監聽*/ 26 WebApiManager.getInstance().init(); 27 } 28 }
啟動程序測試
啟動程序以后我們看到首先刪除了程序項目下面之前的腳本臨時文件,然后重新加載最新腳本文件;成功加載腳本:net.sz.game.test.scripts.webapi.IndexScript, net.sz.game.test.webapi.iscript.IWebApiScript
在瀏覽器輸入http://127.0.0.1/index
成功輸出;
繼續添加login監聽;

1 package net.sz.game.test.scripts.webapi; 2 3 import net.sz.game.engine.nio.nettys.http.NioHttpRequest; 4 import net.sz.game.engine.szlog.SzLogger; 5 import net.sz.game.test.webapi.iscript.IWebApiScript; 6 7 /** 8 * 9 * <br> 10 * author 失足程序員<br> 11 * blog http://www.cnblogs.com/ty408/<br> 12 * mail 492794628@qq.com<br> 13 * phone 13882122019<br> 14 */ 15 public class LoginScript implements IWebApiScript { 16 17 private static SzLogger log = SzLogger.getLogger(); 18 19 @Override 20 public String getRoute() { 21 return "login"; 22 } 23 24 @Override 25 public boolean action(String url, NioHttpRequest request) { 26 /*添加輸出內容,html數據,json數據,txt數據,xml數據,自己定義就好*/ 27 request.addContent("我是明文webapi自動注冊路由 login 歡迎登陸"); 28 return true; 29 } 30 31 }
看看結果:
其實這個自動注冊我們目前依然需要重啟服務;或者不夠智能;
動態加載路由腳本;無需重啟服務
1 package net.sz.game.test.scripts.webapi; 2 3 import java.util.ArrayList; 4 import net.sz.game.engine.nio.nettys.http.NioHttpRequest; 5 import net.sz.game.engine.scripts.manager.ScriptManager; 6 import net.sz.game.engine.szlog.SzLogger; 7 import net.sz.game.test.webapi.iscript.IWebApiScript; 8 9 /** 10 * 11 * <br> 12 * author 失足程序員<br> 13 * blog http://www.cnblogs.com/ty408/<br> 14 * mail 492794628@qq.com<br> 15 * phone 13882122019<br> 16 */ 17 public class ReloadScript implements IWebApiScript { 18 19 private static SzLogger log = SzLogger.getLogger(); 20 21 @Override 22 public String getRoute() { 23 return "reload"; 24 } 25 26 @Override 27 public boolean action(String url, NioHttpRequest request) { 28 /*重新讀取路由腳本*/ 29 ArrayList<String> loadScripts = ScriptManager.getInstance().reload(); 30 String join = "動態加載結果:" + String.join(",", loadScripts); 31 log.error(join); 32 request.addContent(join); 33 return true; 34 } 35 36 }
reload監聽里面處理腳本路由的更新操作;
之所以沒有使用文件更新狀態進行操作,是因為那樣不可控;或許我現在只是發布,但是不需要更新;等待指定時間更新;
重新訪問login
敘述
以上代碼我們完成路由自動注冊,
值的注意的有幾點:
1,我們通過的腳本化實現的路由自動注冊功能;所以代碼是明文的,破壞危險,掛馬危險,較高;
2,我沒有加入驗證機制;這個可以自行約定;確實了iis或tomcat的sesstion 和cokie的這種緩存機制;但好處在於可控性很高,不管是緩存,數據流向,自定義格式;不受iis或Tomcat限制;
3,但是我們可以做到動態發布,動態更新,在不重啟服務的,不影響其他服務的情況下,划分出了,功能獨立開發,獨立部署,互不干涉的情況;
之所以我文章開頭定義微服務也就是這個原理,可以實現服務接口的動態增加刪除,獨立開發,獨立部署,單一流程;當然可以相互協調調用服務接口;
C#.net
在我的版本庫或者叫框架里面依然實現了netty的調用的;
1 using Net.Sz.Framework.Netty; 2 using Net.Sz.Framework.Netty.Http; 3 using System; 4 using System.Collections.Generic; 5 using System.Linq; 6 using System.Text; 7 using System.Threading.Tasks; 8 9 namespace CApp_Webapi 10 { 11 class Program 12 { 13 static void Main(string[] args) 14 { 15 16 HttpServer httpserver = NettyPool.AddHttpBind("127.0.0.1", 9527, 2); 17 18 httpserver.AddHandler("*", new ActionHttpHandler((session) => 19 { 20 session.AddContent("<html><body>webapi!</body></html>"); 21 })); 22 23 httpserver.AddHandler("login", new ActionHttpHandler((session) => 24 { 25 session.AddContent("<html><body>login holle !</body></html>"); 26 })); 27 28 httpserver.Start(); 29 30 } 31 } 32 }
所以就簡單測試,不在過多的去實現和講解理論,都是一樣的;
C#版本,不管你是基於控制台項目,from項目還是service項目;都可以完美的運行;
總結
之前在iis里面創建static變量的共享數據的時候web項目在程序池沒有被回收的情況下,static的資源沒有了;需要加入到web.cache集合里面進行加載和調用;
同樣也是,我是做游戲后端開發的,不管是socket的tcp協議還是socket的http協議,都需要進行處理;但是程序肯定是放在一起,不能經過iis等再次進行調用;
這篇文章在於,實現socket http請求,路由自動注冊概念,微服務概念;已經腳本化的明文處理接口實現;
至於腳本的實現機制;大家可以查看框架代碼或者翻看之前的文章,但是之前的文章里代碼有很多已經和現在服務框架代碼不經相同了;
C#版本的下面測試代碼基本放在了
test的文件夾下面可以直接查看項目對應的測試代碼;
java項目則有所不同,都是maven項目,每一個項目下面都有測試包;
已經測試程序;所以沒有單獨項目;
老鐵們不點個推薦,評論一下嘛?
長友,巨友,段友;天王蓋地虎,寶塔鎮河妖;