如果你不幸的點到了這個文章,那個,這是給我自己看的,我記憶力一直在減退:
10歲以前還能背誦唐詩300首;
10歲以后能記住100多物理、化學、數學公式;
20幾歲,能記住數學分析7大定理;
30幾歲,能記住為數不多的幾個敏捷方法論和實踐;
40幾歲,我開始擔心,這樣下去記憶力極具下降,這,這不行啊。覺得有必要將一些“不常用”的記憶暫存在這里,希望“簡書”還能撐上30年。。。
====== 以下的你看完了如果覺得有用,保存這個筆記,共享記憶給你 =====
2018.3:群暉NAS設置SSH
自己折騰過多個家用NAS的自建以后,去年買了群暉,鑒證了“硬件方案永遠比軟件方案強萬倍”。昨天晚上持續的連接不穩定,群暉的UI不足以定位問題,只能ssh后,自己弄。
問題解決以后忽然感悟:這就是一個不關機的Linux服務器,只用作NAS太浪費了。。。
今天早上,開始安裝MySql,Java,做數據庫遷移,終于把股票抓取、分析的程序弄上去了,以后再也不用隔三差五的自己手工啟動程序抓了。
群暉盒子上面一直放著一個Raspberry Pi,曾經像做“魔鏡”來著的,后來一直沒折騰了,為什么不拿它做一個Jenkins呢?這樣每次改股票代碼、編譯以后,就不用scp到群暉了。于是安裝了Raspbian server。
至此一切順利和美好,直到“設定publickey給群暉,以便Pi能免密碼登錄(才好scp要部署的文件)”,首先是“設定了跟沒設定一樣,還是問密碼”;手工sshd -d和ssh -vvv以后,發現Pi這邊是 “ssh receive packet: type 51” (這是一個Server端返回的publishkey認證錯誤),群暉這邊是:“Failed publickey for steve from 192.168.0.9 port 33492 ... ssh2: RSA SHA256”。
好吧,上面是背景情況,下面是“記憶”:
https://forum.synology.com/enu/viewtopic.php?t=126166
為了防止群暉論壇挺不過30年,這是一些簡述:
根本不是Rasbian的問題,盡管它也有好多ssh的問題,但是這個真的是群暉自己在建立用戶目錄的時候,瞎弄目錄權限。你就得改過來:
*?sudo chmod 755 /volume1/homes/someuser
*?sudo chmod 700 /volume1/homes/someuser/.ssh
*?sudo chmod 644 /volume1/homes/someuser/.ssh/authorized_keys
剩下的都是publickey/privatekey的標準動作。
2018.3:Raspberry PI 安裝Jenkins
誰能想到,安裝Jenkins又花了將近一個下午,教訓是:
Raspbian使用 apt-get install oracle-java8-jdk 安裝Java的時候,默認安裝的是8u65,而Jenkins在某一個版本(2.0?)開始使用https://letsencrypt.org/的服務給插件更新的服務提供SSL,這樣一來,訪問插件更新網站就需要一個證書了(回調安裝時),而Oracle Java在8u101版本以后才支持letsencrypt,這就會在插件更新的時候報錯:SunCertPathBuilderException、PKIX path building failed,別試圖禁用什么SSL降低安全性來解決,也不要自己用keytool增加認證,都失敗了。唯一的路是安裝一個大于101的版本。(這是letsencrypt的支持列表)
卸載已經安裝的8u65
sudo apt-get remove --purge oracle-java8-jdk openjdk-7-jre oracle-java7-jdk openjdk-8-jre
沒有精神再折騰openjdk了,所以不選擇安裝openjdk,還是要Oracle的,需要臨時設定一個安裝源,缺省的只又8u65,通過這個看:
apt-cache policy oracle-java8-jdk
果然沒有吧?下面這三個命令安裝了一個源:
sudo su
echo "deb http://ppa.launchpad.net/webupd8team/java/ubuntu xenial main" | tee /etc/apt/sources.list.d/webupd8team-java.list
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys EEA14886
最后一個命令是,給上面的源一個簽名,以便作為“官方”源被安裝(默認的規則是:不允許安裝第三方源的軟件),運行的時候,立刻報錯:
gpg: failed to start the dirmngr '/usr/bin/dirmngr': 沒有那個文件或目錄
隨即安裝dirmngr:
sudo apt install dirmngr
然后就好了,可以簽名了,可以安裝Java了,可以重新安裝Jenkins了,安裝Jenkins還有一個坑,官方默認的是低版本1.57,最新的是2.111 Beta版和穩定版2.07,按照下面的方法安裝:
wget -q -O - https://jenkins-ci.org/debian/jenkins-ci.org.key | sudo apt-key add -
sudo sh -c 'echo deb http://pkg.jenkins-ci.org/debian binary/ > /etc/apt/sources.list.d/jenkins.list'
sudo apt-get update
sudo apt-get install jenkins -y
安裝2.111,然后訪問,一切正常了。對了,會有一些安裝插件失敗的提示,常規動作解決(反復安裝幾遍),不要自作聰明的刪除一些“沒用”的插件,Jenkins沒到那個聰明程度會告訴你依賴關系,所以不小心你就刪了一個插件的依賴,這個插件就安裝失敗了,之所以要安裝幾遍就好了,是因為這些新安裝的插件也會有依賴關系,安裝幾遍的結果是每次失敗的逐漸減少,最后全部成功。
2018.3: Gradle引入自己/罕見Jar
能想到,讓項目編譯又花了半個晚上么?也是怪我懶,股票程序一直沒有上Jenkins,這個問題是今天才發現的。啥問題呢?股票程序引用了兩個第三方jar文件,做科學計算的,以前都是在.m2目錄的repositories里面做一個目錄,騙maven的,但是這招用在jenkin上,怎么都不行,由于jenkins是root啟動的,起初懷疑是是不是目錄上傳錯了地方,就sudo su了一下,傳到了root的.m2下,手工運行maven(以root),一切正常。可以在Jenkins還是報錯!
查了一下,原來Jenkins的.m2是在/var/lib/jenkins/.m2,不是走~/.m2,嘗試修改settings.xml,指定.m2位置,然后在Jenkins里面指定這個settings.xml,結果還是不行。
情急之下用了粗魯的方法,直接用目錄引用jar文件就行了,比如:
<groupId>steve</groupId>
<artifactId>jsc</artifactId>
<version>1.0</version>
<type>jar</type>
<scope>system</scope>
<systemPath>${project.basedir}/lib/jsc.jar</systemPath>
終于編譯通過了!
不過有一個警告,說是不建議引用的jar在workspace目錄里面,下一個maven版本可能會不允許這樣,強迫癥的勁頭又上來了,換方法!
《plugin》
? ? 《groupId》org.apache.maven.plugins《/groupId》
? ? 《artifactId》maven-install-plugin《/artifactId》
? ? 《version》2.5.2《/version》
? ? 《executions》
? ? ? 《execution》
? ? ? ? ? 《id》install-jsc《/id》
? ? ? ? ? 《phase》clean《/phase》
? ? ? ? ? 《configuration》
? ? ? ? ? ? 《file》${basedir}/lib/jsc.jar《/file》
? ? ? ? ? ? 《repositoryLayout》default《/repositoryLayout》
? ? ? ? ? ? 《groupId》steve《/groupId》
? ? ? ? ? ? 《artifactId》jsc《/artifactId》
? ? ? ? ? ? 《version》1.0《/version》
? ? ? ? ? ? 《packaging》jar《/packaging》
? ? ? ? ? ? 《generatePom》true《/generatePom》
? ? ? ? ? 《/configuration》
? ? ? ? ? 《goals》
? ? ? ? ? ? 《goal》install-file《/goal》
? ? ? ? ? 《/goals》
? ? ? ? 《/execution》
? ? 《/executions》
《/plugin》
增加plugin,在編譯以前現install一個臨時的。
終于優美的解決了。
2018.8:Camunda和Apache NIFI
Camunda是一個工作流,負責“大”業務工作流;NIFI是一個ETL工具,負責“小”技術流;
典型的Camunda應用是:從一個Form開始(不管是誰提交的),經過層層審批后,入庫;從這個角度看,Camunda是一個數據收集工具;
典型的Apache NIFI應用是:當一個請求(或者要求)發送過來后,數據經過層層處理、轉換,最后顯示在頁面上;從這個角度上,NIFI是一個數據轉換工具;
另一個NiFI的應用場景是:從一個請求開始,數據經過層層轉換,最終保存在一個地方;從這個角度看,NIFI除了不支持人工節點,其余的和Camunda一樣。
看一個完整的流程(交房產稅):
驗證用戶是否為房主(通過查詢n個表確定) -> 顯示房產稅金額 (通過查詢表和寫程序計算) -> 提交“交款意愿”(用戶確定交款,或者有申訴什么的)-> 政府部門審批 (可能回答問題以后轉會用戶) -> 用戶使用第三方支付接口交款 -> 政府驗證是否已經收到款 -> 完畢
這個流程可以分為前半段和后半段,在提交“交款意愿”的Form以前,用NIFI,設定流程(誰知道以后的流程和計算方式會不會有變化?如果有,程序不用變,只需要修改NIFI配置就行);從提交“交款意愿”的Form開始,用Camunda,一直到結束(同樣,如果以后審批流程有變化,也不用修改程序)。
2018.8:Camunda的基本使用和怎么使用
參見這個Quick Start,就能對工作流(包括帶有人工審批)有大致的了解,說幾個這里面沒有的:
1、在Service類型的節點中指定Implementation是External,并且給一個Topic,這個Topic的String和寫Java代碼實現這個External Task Client的subscribe(Topic)對應著;
2、lockDuration是干什么的?為了避免多個客戶端處理同一個任務,當一個客戶端拿到以后,鎖定的時間,默認20分鐘。
3、從Moduler的GUIDeploy要是失敗了,看Tomcat下面的catalina.out就知道因為什么。大多數情況是由于模型有問題,部署不上去;
4、定義Form的時候,Form Id不能寫,否則會被當成External Form;正常情況下,定義了Field的form會直接在TaskList web頁面中的Form下看直接顯示;
5、有關怎么顯示Form讓用戶填。Camunda提供四種方式顯示Form,不過我都覺得不夠靈活,還特別破壞架構美感,最終我覺得直接把需要的額數據Post給Camunda的REST API比較好,也就是說,自己寫一個Form(不管在Web還是Mobile),愛寫多花哨就寫多花哨,不管怎么花,數據肯定要提交上來吧,把數據拼成Camunda能認的Json,當作data post給Camunda的Rest Api,完成這個User節點的工作,比如
curl --request POST \
? --url http://192.168.0.24:8080/engine-rest/task/7e2ff9bb-a550-11e8-bd95-00155d590513/submit-form \? //這段是REST API
? --header 'content-type: application/json' \
? --data '{? //以下是POST過去的Data
? ? "variables": {
? ? ? ? "item": {
? ? ? ? ? ? "value": "Computer"
? ? ? ? },
? ? ? ? "amount": {
? ? ? ? ? ? "value": 10000,
? "type":"long"
? ? ? ? }
}
}'
"submit-form" 這個Api就是接受數據,然后標記“任務完成”。其他的Api,看這里
以上是基本使用
以下是怎么用,或者說,如何搭建一個強壯的可擴展應用。
還是拿收房產稅這個事情,假定一個場景,這個平臺需要滿足下面的兩個條件(為了簡單起見,忽略上文說的NIFI的部分,只說后半部分):
1、支持Web和Mobile,老百姓可以提交;
2、三個政府部門涉及到審批,各個部門需要把信息保存在自己的數據庫一份;
分三塊:
1、部署camunda Server。使用Springboot引用Canunda的依賴,自己做一個Camunda Server(不用war和Stand along方式),具體參考這里,需要考慮:
????A、配置數據庫(別用自帶的H2)
? ? B、其他參數的配置(比如Admin用戶名密碼以及自定義UI等)
? ? C、考慮災備服務器和負載均衡,可以查一下Camunda Cluster的信息
? ? D、初始的業務流程放在指定目錄下(啟動就加載),然后想好策略,怎么更新(增加、刪除)這些業務流程
這個東西當作 Microservice的一個節部署在K8s下面(一份或者兩份),并且設定保證活著;
2、做前端的API,支持Web和移動端(為了簡單起見,Web和Mobile都不包括在下面的描述中);用Tomcat + Jersey的Spring Boot構建大框架,在這個程序中向Camunda Server(上面那個)發請求,這些請求包括:啟動一個流程、列出任務、查看任務狀態等等。看看這個會有啟發怎么弄。在這部分,考慮一個事情就行:考慮如何將Camunda的任意一個業務流程都能夠使用同一套代碼兼容,實現:
? ? A、對于不同的業務流程不用修改這里的代碼
? ? B、修改業務流程不需要動這里的代碼
? ? C、增加業務流程不需要動這里的代碼
? ? D、當有了新的流程以后,自動能認,前端只要按照一個名字,就能啟動各種流程。可以考慮使用ConfigHub保存對應關系,把要啟動的流程(人能看懂)和流程的定義文件(bpmn文件)關聯起來
這部分做多個“副本”放在K8s下面,根據網站/移動設備請求使用負載均衡,能夠Auto Scaling;
3、寫各個節點的Service和User Node,這里分成兩種情況
? ? A、不需要Form的(Service Node),比如一個Service節點。可以滿足上面說的:各個部門都要保存在自己的數據庫。在流程中首先加入一個Service Node,然后做這個Node的監聽,收到以后,就寫庫。由于政府有三個部門參與,就寫三個Micro Service,每個針對一個部門,每個MS監聽多個Service Node;這三個MS部署n個在K8s下面,根據流量自動或者手動增減。
? ? B、需要Form的(User Node),上面說了,每一個部門寫一個MS,除了作為Camunda的External Task Client之外,誰說不能接受一般請求呢?都是基于Spring boot結構的,每一個Form寫一個Controller唄。Controller接收到Json數據(前端Api Post過來的),做驗證(可能還有處理)以后,當作data轉提交給Camunda REST API,完成這個流程節點。對于需要Form的這種情況,如果部門的“事兒”不多,可以讓前端API直接調用Camunda的Rest Api。從結構上說,部門級別的處理,應該都在部門的MS里面,由于前端Api是“公用”的,所以不應該包含某一個部門的業務邏輯在里面,也就是說,如果前端Api只管啟動一個流程、發送Json數據給某一個User節點,根本不需要要知道這是哪個部門的。
2018.9: dotnet半日游
突然要接手一個,net項目,對于我這個Java陣營的人來說,雖然不恐懼,但是仍然有些陌生,用了大半天得時間,學到一些基本得東西,希望下次再遇到dotnet得時候,別全忘干凈。
第一部分:概念
- C#和.net:c#是語言,.net是框架,實際上C#是微軟為了讓碼農愛上dotnet而開發得一套類似Java得語言。所以當別人問你是用.net還是C#開發?你就可以抽他一下。
- .net framework和.net core:framework只能再windows平臺使用,每一個windows操作系統都自帶一個某版本的framework(比如windows 10自帶4.7);core是微軟為了進軍其他的操作系統而建立的,有點兒類似jvm;說起歷史,其實framework也是在底層硬件的基礎上封裝的一層,有了這個以后,一些閑人覺得在其他平臺也要有,比如mono、Xamarin等,于是他們就開始自己開發基于不同操作系統的dotnet底層實現,然后微軟覺得不能讓你們瞎搞,所以收購了一些公司出了dotnet core這個“JVM”,但是仍然不能阻止閑人瞎搞的步伐,所以為了防止碎片化,微軟出了一個standard,dotnet standard,就是說“你們可以搞,但是必須按照標準搞,別亂搞”。而后,就有了各種版本的dotnet實現和standard的對應關系。總之,frameworks雖然只能在windows環境下運行,但是他集成了很多windows的功能(DLL),WCF、WPF什么的都可以用;core雖然可以跨平臺,但是有一些功能不支持,畢竟好多windows下面的dll在linux/mac上沒有;如果沒有其他的特殊要求,用微軟自己的dotnet core就好了,別用其他的實現了(這個文章對比了幾個dotnet的實現)。對了,微軟還把dotnet core開源了(別人瞎搞都開源了,自己不開源推不出去啊)。這個文章講的比較清楚。
- runtime和SDK:既然是虛擬機那一套么,所以必然和Java一樣,又java runtime和Java sdk。如果要開發的話,就得裝SDK。
第二部分:環境和開發
- 在Ubuntu上搭建dotnet開發環境:這個文檔說了大致的步驟,注意有一個坑人的地方,人家說支持18.04、16.04,沒說支持18.10和16.10哈,想當然的在16.10搭建的時候,當然出問題了,下面說一下步驟:
A、先裝這個:libicu55(在這兒下載),否則后面會有問題;下載完了以后:dpkg -i libicu52_52.1-3ubuntu0.8_amd64.deb
B、安裝key和依賴:
wget -q https://packages.microsoft.com/config/ubuntu/16.04/packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
sudo apt-get install apt-transport-https
C、按照這個順序裝(不按這個順序會依次提示你:先裝這個,先裝那個的):可以先sudo su,
apt-get install dotnet-runtime-deps-2.1
apt-get install dotnet-runtime-2.1
apt-get install dotnet-sdk-2.1
D、用dotnet --version驗證是否成功了
- Docker和微軟平臺:有了docker以后,在linux世界如魚得水,微軟的windows得要license,所以非常遭唾棄,于是微軟就做了一個windows core這么個玩意,實際上就是一個只有命令行的windows,在此之上,又有了dotnet的docker images,并且微軟自己維護Repo(原本計劃著在docker上編譯甚至debug,但是在windows上都沒有編譯成功呢)
- 開發工具:見識過vs studio小50G的安裝以后,再也不想裝這個開發工具了,見過大的,沒見過和游戲一樣大的IDE。另外一個原因是vs stidio只能在windows上,Ubuntu沒有,看了一些以后,有下面的幾個選擇:
A、rider(Ubuntu可用),這個是和Intellij一個公司的產品,這個IDE是從給vsstudio做插件起步,然后自己做了這么一個。說起插件,就是Resharper,據說裝了以后,vs studio就和和Intellij的Java IDE一樣好了
B、VS Code(Ubuntu可用),這是一個好東西,根本上說,他不是一個IDE,而是一個編輯器,和nodepad++, editplus競爭的,但是就是太出色了,所以成為了前端開發工程師的首選,寫個Angular妥妥兒的,裝了dotnet插件以后,湊活能用吧,語法補全、自動編譯什么的都行;這有一個開發、調試設置的文檔,這兒還有一個,貌似更全面。(這是官方的文檔,主看這個)
C、Mono,這個起初就是在Linux平臺用的,有了Rider,這個就不考慮了;
- 編譯:在Ubuntu上,使用dotnet命令就可以打包、編譯。比如dotnet build。
- 確定自己安裝了哪些dotnet環境:打開注冊表:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full,看Release,對應下面的表:
第三部分:寫代碼
- 這是微軟的自學成才教程
- 這個Repo可以下載多個例子,到例子下面的目錄中,直接dotnet build可以編譯
2018.9:在Ubuntu的下使用.net的sqlite數據庫
在windows環境下使用sqlite特別易如反掌,在nuget下面配好就行,用
System.Data.SqLite,這個是“空包”也就是說,他是幾個包的引用,這幾個包是:
System.Data.SqLite.Core,?System.Data.SqLite.EF6,?System.Data.SqLite.Linq
然后就可以了。在Linux下本想也是這么簡單,但是出現了下面的這個錯誤:Unable to load DLL ‘SQLite.Interop.dll’,找不到這個文件。看了Debug目錄下,的確有這個dll(在x86和x64下面都有),然后把它拷貝到Debug目錄下也不行。
在網上找到,原來是需要在本地環境編譯一把SqLite,由于懶得干編譯,想想要安裝GCC環境就難受,于是嘗試了在網上能找到的全部其他方法,
無一能用
所以,就別浪費時間了,編譯吧,具體步驟在這個帖子里,然后拷貝到Debug目錄下。
(還想到一個偷懶的方法,想直接下載一個ubuntu16.4的編譯好的,結果哪兒都沒有)。