全端 – 挨踢攻城獅學習之路 https://blog.cwlove.idv.tw 不太詳細紀錄 Sat, 20 May 2023 15:06:27 +0000 zh-TW hourly 1 Google Apps Script: 與 Oracle VPS JavaScript 簡易效能測試 https://blog.cwlove.idv.tw/free-gas-and-vps-js-test/ https://blog.cwlove.idv.tw/free-gas-and-vps-js-test/#respond Sun, 05 Feb 2023 15:36:05 +0000 https://blog.cwlove.idv.tw/?p=2542 Google Apps Script 運行速度不佳嗎?

一直覺得 Google Apps Script 寫出來的程式在組資料時速度不佳,直到今天想說用個簡單的測試來跑跑看…

參與的選手

  • Google Apps Script 免費
  • Oracle VPS 免費: AMD EPYC 7551 32-Core Processor 2 個 AMD 型運算 VM (各有 1/8 個 OCPU** 和 1 GB 記憶體),大概 2 核心 * 0.125 可使用
  • 我的電腦 要錢:AMD Ryzen 5 2400G

Google Apps Script 跑 for loop 塞 obj 測試

// 數值加總
function forSumTest() {
  let start = Date.now();
  let sum = 0
  for (let i = 0; i < 1000000000; i++) {
    sum += i
  }
  Logger.log(`加總值為:${sum}`)
  let end = Date.now();
  Logger.log(`Execution time: ${end - start} ms`);
}
// 1705 + 1666 + 1075 + 1598 + 1604 + 1683 + 1528 + 1459 + 1093 + 1023 = 14,434 ms
// 平均 1,443.4 ms

// obj 賦值
function forObjTest() {
  let sum = 0
  let iRound = 10
  let jRound = 100000000
  for (let i = 0; i < iRound; i++) {
    let start = Date.now();
    let obj = {}
    for (let j = 0; j < jRound; j++) {
      obj[j] = j
    }
    let end = Date.now();
    Logger.log(`Execution time: ${end - start} ms`);
    sum += end - start
  }
  Logger.log(`Avg time: ${sum / iRound} ms`);
}
// 平均 5312.3 ms

Oracle VPS Node.js 環境裝起來

安裝 nvm 工具來管理 Node.js
$ curl https://raw.githubusercontent.com/creationix/nvm/v0.39.3/install.sh | bash
$ source ~/.bash_profile 
查看有哪些版本可以安裝
$ nvm ls-remote
...
v16.19.0   (Latest LTS: Gallium)
...
v18.14.0   (Latest LTS: Hydrogen)
...
v19.6.0
裝最新的 LTS 版
$ nvm install v18.14.0
or
$ nvm install --lts
查看
$ nvm list
切換版本(如有裝其他版本)
$ nvm use v16.19
切換最新的 LTS 版本
$ nvm use --lts
設定預設版本(如有裝其他版本)
$ nvm alias default v16.19

Oracle VPS 跑 for loop 塞 obj 測試

// 數字加總
let start = Date.now();
let sum = 0
for (let i = 0; i < 1000000000; i++) {
  sum += i
}
console.log(`加總值為:${sum}`)
let end = Date.now();
console.log(`Execution time: ${end - start} ms`);
// Oracle VPS
// 3273 + 3141 + 3667 + 3197 + 3203 + 3192 + 3197 + 3183 + 3722 + 3203 = 32,978 ms
// 平均 3,297.8 ms

// obj 賦值
let sum = 0
let iRound = 10
let jRound = 100000000
for (let i = 0; i < iRound; i++) {
  let start = Date.now();
  let obj = {}
  for (let j = 0; j < jRound; j++) {
    obj[j] = j
  }
  let end = Date.now();
  console.log(`Execution time: ${end - start} ms`);
  sum += end - start
}
console.log(`Avg time: ${sum / iRound} ms`);
// JavaScript heap out of memory 炸了

AMD Ryzen5 2400G 跑 for loop 塞 obj 測試

let start = Date.now();
let sum = 0
for (let i = 0; i < 1000000000; i++) {
  sum += i
}
console.log(`加總值為:${sum}`)
let end = Date.now();
console.log(`Execution time: ${end - start} ms`);
// AMD 2400G 效能模式
// 858 + 868 + 857 + 900 + 862 + 858 + 860 + 869 + 859 + 870 = 8,661 ms
// 平均 866.1 ms

let sum = 0
let iRound = 10
let jRound = 100000000
for (let i = 0; i < iRound; i++) {
  let start = Date.now();
  let obj = {}
  for (let j = 0; j < jRound; j++) {
    obj[j] = j
  }
  let end = Date.now();
  console.log(`Execution time: ${end - start} ms`);
  sum += end - start
}
console.log(`Avg time: ${sum / iRound} ms`);
// 平均 3174.5 ms

大出意料之外,是我 Code 寫不好,錯怪他了。但發布出來的 Web App 前端在調用 GAS 不做任何邏輯直接 return 出來還是會有 700 ~ 1,000 ms 的等待 response 時間,GAS 讀試算表 400 筆資料不做任何處理要 300 ms ~ 700 ms,在初始頁面時也慢,適合寫工具就好。

Google Apps ScriptOracle VPSAMD Ryzen5 2400G
加總1,443.4 ms3,297.8 ms866.1 ms
obj 賦值5312.3 ms— 炸了 —3174.5 ms
]]>
https://blog.cwlove.idv.tw/free-gas-and-vps-js-test/feed/ 0
PHP:Line Bot 開發 Server 問題紀錄 https://blog.cwlove.idv.tw/php-line-bot-notes/ https://blog.cwlove.idv.tw/php-line-bot-notes/#respond Fri, 03 Jun 2022 16:10:38 +0000 https://blog.cwlove.idv.tw/?p=2297
  • 問題:有沒教學或範本可以參考
  • 解決:佛心 Line Bot 開發教學,基礎範例程式碼 (PHP) – 輕量版 LINEBotTiny.php | 旋風之音 GoneTone (reh.tw)
    • 問題:本地測試都可以正常回應,上正式站 VPS 主機卻已讀不回,查看 PHP 沒噴 Error log
    • 解決:測試將 SELINUX 設為 0 後正常,爬文了下 LINEBotTiny.php 裡有使用 file_get_contents() 方法需要
    $ sudo setsebool -P httpd_can_network_connect on
    • 問題:存放設定檔及 assets 可被下載
    • 解決:調整 Nginx 設定後 reload
    location ~ \.(ini|env|conf)$ {
            deny all;
            return 404;
    }
    location /assets {
            deny all;
            return 404;
    }
    $ sudo nginx -s reload
    • 問題:連線資料庫顯示 Uncaught PDOException: could not find driver ,但程式碼沒毛病啊
    • 解決:調整 php.ini 把 pdo extension 打開
    extension=pdo_mysql
    • 問題:本地開發要怎麼讓 Webhook 連到本機?
    • 解決:使用 ngrok,下載後執行
    $ ngrok http 80
    
    Session Status                online
    Session Expires               1 hour, 59 minutes
    Update                        update available (version 3.0.4, Ctrl-U to update)
    Terms of Service              https://ngrok.com/tos
    Version                       3.0.3
    Region                        Japan (jp)
    Latency                       calculating...
    Web Interface                 http://127.0.0.1:4040
    Forwarding                    https://15c9-125-231-144-48.jp.ngrok.io -> http://localhost:80
    
    把 https 的連結貼到 Webhook URL 就可以了
    • 問題:如何同步到 Production 環境?
    • 解決:使用 VS Code 外掛 SFTP

    Ctrl + Shifp + P

    產生的 sftp.json 檔
    {
        "name": "App Server",
        "host": "域名",
        "protocol": "sftp",
        "port": 22,
        "username": "vps 主機帳號",
        "remotePath": "遠端目錄",
        "uploadOnSave": false, 
        "privateKeyPath": "D:\\私鑰位置", // Windows 每一層目錄都要兩個 \\ 喔
        "passphrase": "私鑰密碼",
        "watcher": {
            "files": "**/*",
            "autoUpload": true,
            "autoDelete": true
        },
        "ignore": [
            ".vscode",
            ".git",
            ".DS_Store",
            "README.md",
            "環境設定檔"
        ]
    }
    

    SFTP: Sync Local ➝ Remote 這樣就可以即時同步,測試結果啦

    如遇彈跳窗說明遠端目錄沒有權限話,可以修改遠端目錄權限,因為是 Nginx 使用者資料夾,所以用 setfacl 給予權限
    $ sudo setfacl -R -m user:帳號:rwx 目錄
    • 問題:Flex Message 怎麼寫?
    • 解決:除了上面佛心網友的教學,可以直接使用官方的 FLEX MESSAGE SIMULATOR 來製作,非常方便
    ]]>
    https://blog.cwlove.idv.tw/php-line-bot-notes/feed/ 0
    Tampermonkey:網頁表單自動輸入簡易相加的計算驗證碼 https://blog.cwlove.idv.tw/tampermonkey-simple-form-input-calc-add/ https://blog.cwlove.idv.tw/tampermonkey-simple-form-input-calc-add/#respond Sun, 17 Oct 2021 05:18:35 +0000 https://blog.cwlove.idv.tw/?p=2244 公司的訂便當系統登入都要輸入提示的計算相加的結果做為驗證

    帳號、密碼瀏覽器會幫忙自動帶入了,但計算驗證要自己填
    其實問題都是很簡單的數字相加,懶人的想寫腳本自動填入快速登入,頭次嘗鮮覺得很有趣
    先分享一下網友做的 Tampermonkey 範例教學,依樣畫葫蘆寫了

    // ==UserScript==
    // @name         calcDinBenDon
    // @namespace    http://tampermonkey.net/
    // @version      0.1
    // @description  try to take over the world!
    // @author       You
    //// @include      https://dinbendon.net/*
    // @match        https://dinbendon.net/do/login
    // @icon         https://www.google.com/s2/favicons?domain=dinbendon.net
    // @grant        none
    // ==/UserScript==
    
    (function() {
        'use strict';
         let anwser = "got Error"
         let question = document.querySelectorAll(".alignRight")[2].innerText;
         anwser = question.match(/\d+/g).map(Number).reduce((a, b) => a + b);
         document.querySelector('input[name="result"]').value = anwser
    })();

    很簡單的就是去抓取網頁上的字串文字,取出數字為陣列再轉換型別加總,最後填入表格內

    ]]>
    https://blog.cwlove.idv.tw/tampermonkey-simple-form-input-calc-add/feed/ 0
    WordPress:PHP 7.4 + Opcache + Update Plugin = 502 Bad Gateway https://blog.cwlove.idv.tw/wordpress-php-74-opcache-502-bad-gateway/ https://blog.cwlove.idv.tw/wordpress-php-74-opcache-502-bad-gateway/#respond Sat, 11 Sep 2021 13:32:17 +0000 https://blog.cwlove.idv.tw/?p=2236 問題主要是 WordPress 使用 PHP 7.4 下,很容易在更新外掛後噴 502 Bad Gateway,網站錯誤畫面內容如下

    An error occurred.
    Sorry, the page you are looking for is currently unavailable.
    Please try again later.
    If you are the system administrator of this resource then you should check the error log for details.
    Faithfully yours, nginx.後來測試將 Opcache 關掉後就正常。

    後來將 Opcache 關掉就正常,便嘗試找哪一項設定問題。

    原本設定如下

    [opcache]
    opcache.enable=1
    opcache.enable_cli=1
    opcache.memory_consumption=64
    opcache.interned_strings_buffer=8
    opcache.max_accelerated_files=10000
    opcache.validate_timestamps=1
    opcache.revalidate_freq=60
    opcache.save_comments=0
    opcache.file_cache=/tmp

    將最後一項 opcache.file_cache=/tmp 拿掉就正常了。

    對 PHP 及架構不熟,暫時先這樣處理。

    ]]>
    https://blog.cwlove.idv.tw/wordpress-php-74-opcache-502-bad-gateway/feed/ 0
    Javascript:IOS 14 Safari window.open 沒有提示彈跳視窗 https://blog.cwlove.idv.tw/js-ios-14-safari-window-open/ https://blog.cwlove.idv.tw/js-ios-14-safari-window-open/#respond Thu, 04 Mar 2021 14:44:47 +0000 https://blog.cwlove.idv.tw/?p=2158 原先寫法是

    this.getLink(ID).then(res => {
      window.open(res, '_blank', 'height=800,width=1050');
    });

    在 PC、Mobile 的 Safari、Chrome 都會顯示有彈跳視窗需允許才能打開,這沒什麼問題,允許就好
    但在 IOS 14 的 Safari 連提示都沒有,只能從設定裡去動,但不可能教使用者都要去改手機設定
    因此找了下解法找到這篇:window.open在Safari中不能打开的问题

    改成以下寫法就解決了,可直接彈出新視窗不需按允許

    var winRef = window.open('', '_blank', 'height=800,width=1050');
    this.getLink(ID).then(res => (winRef.location = res));
    ]]>
    https://blog.cwlove.idv.tw/js-ios-14-safari-window-open/feed/ 0
    Javascript:關閉分頁、瀏覽器事件動作 https://blog.cwlove.idv.tw/js-event-close-tab-browser-beacon-api/ https://blog.cwlove.idv.tw/js-event-close-tab-browser-beacon-api/#respond Thu, 04 Mar 2021 14:30:09 +0000 https://blog.cwlove.idv.tw/?p=2151 網站需求要在關閉分頁、瀏覽器後,將用戶登出。因此需要
    1.有個事件監聽,能在各大 PC、Mobile 瀏覽器在關閉分頁或瀏覽器後執行程式
    2.該程式要能成功打 API 告知後端該用戶要登出

    踩坑踩很久,先分享一下找到的文章,快速出坑

    首先第一篇發送 HTTP Request 諸多方法,除了作者提到 Service Worker 本身比較麻煩,我看了文件還真是很麻煩,故沒有測
    其他測過結果 Beacon API 瀏覽器相容最好,因此有此需求,請直接用它吧。

    再來分享事件監聽我嘗試過下列寫法,電腦版 Safari、Chrome、Firefox、手機版 Chrome、Firefox 都能生效,
    唯獨手機版 Safari 不行(IOS 版本12、14 都測過)。這網站可以測事件有無觸發,測完放棄治療IOS Safari。

    // let isIOS = navigator.userAgent.match(/iPad/i) || navigator.userAgent.match(/iPhone/i);
    // eventName = isIOS ? 'pagehide' : 'beforeunload'
    
    // 電腦版 Safari 能生效
    window.addEventListener('pagehide', e => this.beforeUnload()); 
    // 電腦版 Safari、Chrome、Firefox 能生效
    window.addEventListener('beforeunload' 或 'unload', e => this.beforeUnload());
    // 手機版 Chrome、Firefox 能生效
    document.addEventListener('visibilitychange', e => this.beforeUnload()); 

    再來第二篇 Beacon API 照可能會碰到跨域問題,而開發環境已經設 * 還是不能跑,參考第四篇得到以下改法可以參考一下

    let blog = new Blob(
      [
        JSON.stringify({
          Status: status,
          Account: account,
        }),
      ],
      // { type: 'application/json; charset=UTF-8' }
      { type: 'text/plain; charset=UTF-8' }
    );
    
    navigator.sendBeacon(
      apiHost + '/api/demoUpdateLoginStatus',
      blog
    );

    以上參考。

    ]]>
    https://blog.cwlove.idv.tw/js-event-close-tab-browser-beacon-api/feed/ 0
    WSL2:運行 npm install 錯誤 https://blog.cwlove.idv.tw/wsl2-npm-install-no-such-file-or-directory/ https://blog.cwlove.idv.tw/wsl2-npm-install-no-such-file-or-directory/#respond Sat, 16 Jan 2021 00:29:56 +0000 https://blog.cwlove.idv.tw/?p=2131 錯誤提示:-bash: /mnt/c/Program Files/nodejs/npm: /bin/sh^M: bad interpreter: No such file or directory
    餵狗得到這篇解法:Cannot run NPM Commands

    看覺得是環境變數問題,所以照著操作確認
    $ echo $PATH
    得到/mnt/c… 等許多for Windows 用的路徑,因此需要調整為 WSL 下使用的,參考解答

    $ vim ~/.bashrc
    加入 PATH=$(echo “$PATH” | sed -e ‘s/:\/mnt.*//g’) # strip out problematic Windows %PATH%
    完成後
    source ~/.bashrc

    $ echo $PATH
    /home/qoo/go/bin:/usr/lib/go-1.15/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

    就可以順利 $ npm install 了

    ]]>
    https://blog.cwlove.idv.tw/wsl2-npm-install-no-such-file-or-directory/feed/ 0
    Go:取前端傳入的用戶 IP https://blog.cwlove.idv.tw/go-haproxy-get-client-ip/ https://blog.cwlove.idv.tw/go-haproxy-get-client-ip/#respond Fri, 08 Jan 2021 04:07:49 +0000 https://blog.cwlove.idv.tw/?p=2118 前端:Nginx 代理
    後端:Haproxy + Go
    取 IP 部分主要參考這篇文章:GO获取客户端IP地址,以下可取得 IP

    func GetClientIP(r *http.Request) (clientIP string) {
    	clientIP, _, _ = net.SplitHostPort(r.RemoteAddr)
    	if clientIP == "::1" {
    		clientIP = "127.0.0.1"
    	}
    	if ip := r.Header.Get("X-Forwarded-For"); ip != "" {
    		remoteAddress := strings.Split(ip, ",")
    		clientIP = remoteAddress[0]
    	}
    	return
    }

    一開始由外部網路連入,取到的 IP 都是 127.0.0.1,嘗試了在前端 Nginx default.conf 加入了

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    未起作用,突然想起後端前有 HAProxy,於是翻閱文件找到這段

    option forwardfor :如果服务器上的应用程序想记录发起请求的客户端的IP地址,需要在HAProxy上配置此选项,这样

                                   HAProxy会把客户端的IP信息发送给服务器,在HTTP请求中添加”X-Forwarded-For”字段。

    故調整 HAProxy haproxy.cfg 在 defaults 底下加入 option forwardfor

        defaults
            option forwardfor
    Log 出來顯示正確
    X-Forwarded-For: 202.102.86.60
    RemoteIP: 202.102.86.60 OsName: Windows BrowserName: Chrome

    另外要抓取來源國家可以自建服務,參考這裡,都幫你寫好了:https://github.com/ip2location/ip2location-go

    ]]>
    https://blog.cwlove.idv.tw/go-haproxy-get-client-ip/feed/ 0
    Vue.js:已經重裝Node.js,Vue Create 仍失敗 https://blog.cwlove.idv.tw/vue-create-rejected-by-your-operating-system/ https://blog.cwlove.idv.tw/vue-create-rejected-by-your-operating-system/#respond Thu, 12 Mar 2020 05:06:56 +0000 https://blog.cwlove.idv.tw/?p=1898 Vue CLI v4.2.2,公司電腦 Create Project 時,都會跳出如下錯誤的結尾

    npm ERR! The operation was rejected by your operating system.
    npm ERR! It's possible that the file was already in use (by a text editor or antivirus),
    npm ERR! or that you lack permissions to access it.
    npm ERR!
    npm ERR! If you believe this might be a permissions issue, please double-check the
    npm ERR! permissions of the file and its containing directories, or try running
    npm ERR! the command again as root/Administrator.

    使用yarn也會跳錯,已經clean cache、更新npm、更換npm source、reboot電腦
    重裝nodejs、vue、vue-cli,清除所有npm、npm-cache、刪除 .vuerc檔都無法解決
    A同事也發生一樣狀況,但B同事可以成功,最後檢查到.vuerc 有差異

    我的預設內容是

    {
      "useTaobaoRegistry": true,
      "packageManager": "npm"
    }

    將 “useTaobaoRegistry” 改為 false 就可以了。

    > notepad %USERPROFILE%\.vuerc
    {
      "useTaobaoRegistry": false,
      "packageManager": "npm"
    }
    ]]>
    https://blog.cwlove.idv.tw/vue-create-rejected-by-your-operating-system/feed/ 0
    Vue.js:解決Vuex重新整理頁面,State就被清掉問題 https://blog.cwlove.idv.tw/vue-vuex-refresh-state-session-storage/ https://blog.cwlove.idv.tw/vue-vuex-refresh-state-session-storage/#respond Thu, 05 Mar 2020 05:31:16 +0000 https://blog.cwlove.idv.tw/?p=1887 使用 Vuex 儲存使用者登入資訊時,因重新整理會導致 Vuex 狀態被清除而網頁回到登出狀態,
    故要先將狀態儲存到 Session Storage,頁面載入時再取回來

    來源:解決vuex重新整理頁面就恢復初始化的方法之一

           created(){
            //在頁面載入時讀取sessionStorage裡的狀態資訊
                if (sessionStorage.getItem("store") ) {
                    this.$store.replaceState(Object.assign({}, this.$store.state,JSON.parse(sessionStorage.getItem("store"))))
                }
    
                //在頁面重新整理時將vuex裡的資訊儲存到sessionStorage裡
                window.addEventListener("beforeunload",()=>{
                    sessionStorage.setItem("store",JSON.stringify(this.$store.state))
                })
            },

    記得登出時需要清除Session、Vuex,否則怎麼按登出資料都還在

    ]]>
    https://blog.cwlove.idv.tw/vue-vuex-refresh-state-session-storage/feed/ 0