2020年11月23日 星期一

[網站開發] 美股搜尋網站 (1) 後端程式開發 - 使用Azure Cosmos DB & Azure Function

去年自己寫了個美股掃雷網: https://norn-minehunter.zmcx16.moe/

至於選股則是都透過Finviz的screener功能: https://finviz.com/screener.ashx?v=111&ft=4

雖然說Finviz真的很好用, 功能也非常強大, 可是能看的東西都是已知的基本面或技術分析指標, 沒辦法做自己的客製化指標, 變成我每次都得先用Finviz的screener先搜尋過濾, 在用自己的指標挑選一次, 這樣很麻煩又會有缺漏, 就想說還是自己來做個美股搜尋器好了。

再來就是做搜尋器最大的問題點了, 我要怎麼取得所有美股的數據資料? 美股大概有一萬檔以上的上市股票, 扣掉市值太低以及成交量太低的個股, 也還是有近3000~6000檔個股。 而我目前使用的數據源都是免費的, 只要使用量太大就會被ban IP, 如果乖乖的在不被ban IP的情況去取得所有美股資料的話, 目前估算抓完一輪至少要一個多禮拜, 這樣每次過濾搜尋的資料會離得目前市價太遠, 會有工具失真的問題...。

以自己來說要達到搜尋器可用等級的話, 數據資料最多不能差超過一天, 所以我至少要有7個IP以上每天不斷的抓數據才有辦法, 幸好之後有想到辦法, 詳情可以參考以下這篇:

[雲端服務] 被ban ip又沒有穩定的proxy server怎麼辦? 用Azure Function自己架個代理伺服器吧

Ban IP的問題解決了, 再來就是伺服器工作量的問題, 基本上就是要寫個一直取得美股數據並生成報表的程式, 由於自己的Azure VM是最低階規格, 而且已經掛了幾個我的網站服務, 所以就不太想把這個一直忙跟佔網路流量的程式放在自己的Azure VM server上了。思考了下最後決定把這個程式寫在Azure Function上, 像這種 I/O bound的工作放在Azure Function可以幾乎花不到什麼錢, 至於取得的數據部分, 原本是想直接上傳到我自己的Azure VM上或是存到Azure storage account, 不過剛好最近玩Azure時有注意到他們的Azure Cosmos DB的免費層還蠻佛心的, 剛好又想玩玩NoSQL, 就決定趁這次機會玩玩看。

下面是Azure Cosmos DB免費層規格:


RU是request unit的縮寫, 認真講還真看不懂要怎麼換算, 不過以容量來說有5G已經很佛心了, 而container則是有限制最多只能開到25個, 以我來說算綽綽有餘了。 另外由於Azure Cosmos DB分片是以10G為單位, 以免費層來說等於不會有用到分片的機會, 沒辦法享受到NoSQL水平擴展的魅力。

建好的DB概觀圖如下, 目前正在用Azure Function慢慢抓資料放到DB中, 這資料跟索引大小的比例真是讓人愉悅XD



下圖是Azure Cosmos DB的資料總管, 可以直接從網頁看到你的資料庫內容, 目前我主要拿來放每檔美股的基本以及生成掃雷報表的分數結果, 用平均分數當作Partition Key, 不過因為容量只有5G, 基本上也沒有這個key的表現機會就是了。 另外從圖中可以看到, 資料是以JSON表示, 另外Azure也很貼心的提供SQL command支援, 不過畢竟是NoSQL, 已經不是關聯式資料庫了, 應該還是有些語法不支援吧, 這個就有空在研究了。 另外很可惜的是Azure Cosmos DB免費層不支援VNet, 這代表我沒辦法設定防火牆只讓我的Azure入口網站還有Azure Function存取, 只能用Authorization Key當作最終保護DB的手段。



基本上都是用async的function讀寫, 寫入的時候都會指定你資料的Partition Key, 另外奇怪的是範例上的讀寫資料都是用自己寫的class定義document的結構, 在讓SDK把資料轉入 / 出 定義好的class物件, 基本上這樣超麻煩..., 畢竟這等於每種類型的document都得寫個class去定義schema, 這樣跟關聯式資料庫時定義schema不是沒兩樣嗎..., 如果是多層的json資料不是會寫到死, 更何況json還有可能是動態的, 如果圖方便用字串存那之後query又得去parser字串效能不就悲劇了嗎?

因為範例那種作法超麻煩, 所以我自己是把有可能是動態的資料都直接宣告成dynamic了, 而且這樣寫進去的資料從Azure資料總管看也是多階層的JSON, 而讀取的話我是直接用dynamic去接, 在用JSON parser去parse我要的資料, 這樣效能應該是會比自己定義class去存取慢, 不過基本上不用在意效能的地方很方便就是了, 不如說有可能動態階層的document也只能這樣讀吧?



這次分享就到這邊, 基本上後端這樣就搞定了, 再來就是苦力的前端, 基本上大多數網站的Stock Screener的頁面都大同小異, 應該是不用花太多心力刻啦, 不過我自己每次寫前端都覺得超累, 不像後端寫好功能邏輯就好, 前端layout跟微調每次都得花大把時間, 可以的話能不寫還真想不寫XD

2020年11月22日 星期日

[雲端服務] 被ban ip又沒有穩定的proxy server怎麼辦? 用Azure Function自己架個代理伺服器吧

由於自己之前做的掃雷網會用到YAHOO財經API, 而YAHOO財經API是有限制的, 只要你一分鐘內打太多request, 就會被ban ip大概幾分鐘左右。 由於這個限制, 所以如果我想從YAHOO拿到所有美股的資料的話, 扣掉市值跟成交量太小的個股至少也要花一個多禮拜才有辦法拿到所有資料。

要解決這個問題, 一個就是買YAHOO財經的付費數據源, 不過那個夭壽貴也用不到那麼多功能, 所以不考慮; 而第二種解決辦法就是看有沒有辦法生多個IP, 或是找proxy server的免費或付費服務。 基本上要多個IP就是得花錢多辦網路, 而免費的proxy服務又不穩定且常常失效, 付費的proxy也不確定是不是能符合要求不踩雷...。

想了些方案後忽然想到, 現在市面上的雲端服務都有一定額度的免費用量, 應該可以有辦法在不花錢的情況下解決這問題吧!! 基本上先不考慮要錢的VM, 以Azure來說可以選的就是Azure App Service以及Azure Function了。

以下是Azure web app以及Azure function的免費層價位:

Azure App Service(免費層最多10個app): 


Azure Function:


以上述兩種服務來說, Azure App Service最多可以開10個代表我最多可以拿到10組IP, 而Azure Function沒有個數限制, 代表我可以拿到的IP數沒有限制, 用Azure App Service的話只要每天超過1小時CPU用量當天就會不給連了, 而Azure Function則是要小心不要超過一百萬次 * 資源取用量。

再來就是POC了, 下面我寫了簡單的proxy轉發程式, 然後一次部署了五台Azure Function的服務, 分別開在不同的地區:



再來開個服務同時建五個async task往這五個proxy server打, 在用這些資料生成各美股的掃雷報表, 下圖是其中一個Azure Function的資源使用量:


沒想到資源的使用量比我想的大得多, 畢竟每生成一個報表都要打十幾個request, 稍微來換算一下, 一個小時我的執行次數就有2360次, 資源用量則是94.7M, 假設我繼續這樣不眠不休全力運轉打下去, 一個月的總用量:

-----

執行次數: 2360 * 24 * 30 = 1699200次

資源用量: 94.7M * 24 * 30 / 1024 = 68.69 GB-s

再加上我一次開五台, 所以總共是:

執行次數: 1699200 * 5 = 8496000次

資源用量: 68.69 * 5 = 343.45 GB-s

-----

資源用量離40萬GB-s還差得遠, 可是執行次數已經超過免費額度了, 所以一個月的費用為:
 (8496000- 1000000免費額度) / 1000000 * 6.011 = 45.05 台幣。

可以看見, 因為執行的都是I/O bound的工作, 所以用不到什記憶體, 可是執行次數還是閃不掉的, 不過不要整天 + 開多個服務去打request的話, 要用到一百萬次執行其實也蠻難的。不過這做法最讚的是, 我如果分散流量打得更開, 我要有多少IP就有多少IP, 根本就是Unlimited IP Works了!!


至於呼叫次數太多的問題, 我目前是打算在開個Azure Function的服務, 不過我這次會把生成掃雷報表的後端程式直接放上去, 這樣執行次數應該可以變成1/10以下, 相對的資源用量則會上漲許多, 不過看了上面的計算結果, I/O bound的工作資源用量要爆應該很難, 試試看就知道了XD

2020年11月15日 星期日

[重大更新] MahoMangaDownloaderVer13.0 & Ver13.1更新

Ver13.1 更新內容:

  • 改善dmzj頁數卡住問題

檔案位址:
https://drive.google.com/file/d/1Rd9yasvxPCFF1HycGti2kF8NytAzqQ6F/view?usp=sharing

32位元版本:
https://drive.google.com/file/d/13p9yAbJO5M8F6PQNWHpmntFOz53jWrgf/view?usp=sharing

解壓密碼:zmcx16

-------- 我是分隔線 --------


上個月有某個使用者回報下載器在某網站會有閃退的問題, 當時因為我沒辦法reproduce那問題, 所以也只能先放置並請對方先拿其他網站擋著用, 結果昨天開始我這邊終於能重現一樣的問題了, 看了下event log crash的點在CefSharp的process上, 只要有用到該process下載個幾分鐘後他就會自己crash, 之後有去Cefsharp的github issue找原因, 通常這類問題出在Chromium上比較多(畢竟CefSharp只是用.NET包裝一層Chromium的framework),遇到這問題也只能等Chromium update修bug, 而這個閃退的問題在我update CefSharp到最新版後就沒有再發生了。

再來就是問題點了, 基本上下載器我一直避免去更新第三方套件, 因為之前更新後總會有幾個使用者回報更新後出問題, 然後大多數是環境問題, 所以我都盡量避免去更新套件, 不過現在這閃退的問題不處理也不行, 偏偏CefSharp剛好我用的下一版本開始改成VC++2013 -> VC++ 2015, 這變成只要更新完下載器大多數使用者都會開不起來, 得安裝VC++ 2015 可轉散發套件才行...。

因為下載器本身是可攜式軟體, 我也不想主動幫使用者安裝套件, 所以還是跟以前一樣只能請使用者自己安裝了, 另外為了避免一堆人線上更新完後程式開不起來跑來問, 所以我有多做一個VC++ 2015的檢查, 檢查沒裝會主動跳訊息通知, 請使用者在自行去Microsoft網站下載安裝。


重要事項再放大字重點說明:

"MahoMangaDownloaderVer13.0必須安裝VC++ 2015 可轉散發套件, 原本的VC++2013只適用在下載器Ver12.5之前的版本!"

VC++ 2015 可轉散發套件下載位置:
https://www.microsoft.com/zh-tw/download/details.aspx?id=48145


再來就是固定的推坑時間, 這次想介紹的是很喜歡的作者: 羽海野千花

代表作品是蜂蜜幸運草(已完結)以及三月的獅子(不定期連載中)

這兩部作品基本上風格很像, 羽海野千花我覺得最厲害的地方就是他的作品溫差非常大, 溫馨愉快跟黑暗沉重的落差非常大, 簡單來說就是非常重口味(精神上), 搞笑愉快的時候非常愉悅, 嚴肅劇情時則是看到快胃痛, 而且除了最主要的主角群們以外, 每個配角也都有屬於自己的故事, 讓人更能對各個角色投注感情, 另外在三月的獅子更是加入了不少社會上最難搞的兩大問題: 家庭 & 霸凌問題, 描寫的非常有真實感以及讓人有代入感, 另外還有最最最厲害的地方就是"青春", 這作者的作品有滿滿的青春味, 常常看著都覺得自己年輕了十歲以上XD 非常推薦這兩部作品!!

以下是蜂蜜幸運草以及三月的獅子的部分內容:

蜂蜜幸運草: 存在感薄弱的男主角竹本生日:







對未來迷茫的竹本, 畢業作品中途打分時忽然來個神救援:




這個青春之塔後面還有各種小故事, 就先不捏他了XD

三月的獅子 - 第一話開頭:





------------------







被領養之後,沒想到卻讓對方家庭關係破裂...






男主角離開之後, 在某個機緣下被川本一家撿到(?)





將棋的世界







這是很嚴肅的將棋漫畫!!











這次介紹就到這裡, 蜂蜜幸運草除了原作漫畫以外, 還有動畫跟電影還有電視劇, 當初電視劇還是日劇台劇兩邊各自拍一部! 三月的獅子也有動畫, 不論是從漫畫還是動畫入坑都很推薦!!


Ver13.0 更新內容:

* 更新CefSharp套件 (63.0.1 -> 85.3.130)


下載器Demo圖:




介紹:

https://project.zmcx16.moe/?page=mahomangadownloader


MahoMangaDownloader下載器主要為幫助使用者改善線上漫畫的閱覽體驗, 如果試看的漫畫您非常喜歡, 也請麻煩購買正版支持原作者, 讓作家們能繼續創造出下一部更棒的作品。


環境需求

.Net framework 4.5.2或以上的版本

Visual C++ 2015 (只能安裝2015版, 其他版本不行)


簡單除錯:

* 如果下載失敗, 麻煩先用瀏覽器測試看資源是否存活。

* 如果能正常用瀏覽器瀏覽, 麻煩先查看LogFiles資料夾內的log檔案看錯誤訊息為何。

* 回報問題時, 麻煩提供有問題的網址以及log內容, 這樣我才有辦法測試找問題原因。


檔案位址:

https://drive.google.com/file/d/1fgZNxWlC86Uj7Hi_ouKgPgXGmhYBFufT/view?usp=sharing


32位元版本:

https://drive.google.com/file/d/1J6DAaVAUVhZcMvve4AplkFlIOyAuYMLe/view?usp=sharing


解壓密碼:zmcx16


免責聲明:

******************

MahoMangaDownloader僅作為學術研究使用,禁止利用本程式行非法用途。