大話性能測試系列(3)- 常用的性能指標

如果你對性能測試感興趣,但是又不熟悉理論知識,可以看下面的系列文章

https://www.cnblogs.com/poloyy/category/1620792.html

 

兩種性能指標

  • 業務指標
  • 技術指標

通常我們會從兩個層面定義性能場景的需求指標,它們有映射關係,技術指標不能脫離業務指標

 

併發

狹義

指同一個時間點執行相同的操作(如:秒殺)

 

廣義

  • 同一時間點,向服務器發起的請求(可能是不同的請求)
  • 只要向服務器發起請求,那麼服務器在這一時間點內都會收到請求(不管是不是同一個請求)

 

場景類比

高速公路上,同時有多少輛車經過同一個關卡,但不一定是同一個牌子的汽車

 

併發用戶數(重點)

同一時間點,發出請求的用戶數,一個用戶可以發出多個請求

 

和併發的關係

假設有 10 個用戶數,每個用戶同一時間點內發起 2 個請求,那麼服務器收到的請求併發數就是 20

 

相關概念

  • 系統用戶數:系統累計註冊用戶數,不一定在線
  • 在線用戶數:在線用戶可能是正常發起請求,也可能只是掛機啥操作都沒有【在線用戶數併發用戶數】
  • 線程數:在 jmeter 中,線程數和併發用戶數等價

 

事務

  • 客戶端向服務器發送請求,然後服務器做出響應的過程
  • 登錄、註冊、下單等功能都屬於一個事務
  • 一個事務可能會發起多個請求

 

jmeter 相關

jmerter 中,默認一個接口請求,就是一個事務;但也支持多個接口整合成一個事務

 

注意點

若一個業務或事務有多個接口,那麼多個單接口的性能指標值相加 業務或事務的性能指標值

 

再來看看有哪些常見的性能指標值

 

響應時間(Respose Time)

概念:從發起請求到收到請求響應的時間

包含:Request Time 和 Response Time

等價:發起請求網絡傳輸時間 + 服務器處理時間 + 返迴響應網絡傳輸時間

 

重點

在做性能測試時,要盡可能的降低網絡傳輸時間,這樣最終得出的 RT 會無限接近服務器處理時間,所以我們要把網絡環境搞好

 

事務請求響應時間

完成單個事務所用的時間,可能包含了多個請求

 

TPS(Transaction Per Second,最主要的指標)

服務器每秒處理事務數,衡量服務器處理能力的最主要指標

 

知道 T 是如何定義的

  • 在不同的行業、業務中,TPS 定義的顆粒度可能是不同的
  • 所以不管什麼情況下,需要做性能測試的業務的相關方都要知道你的 T 是如何定義的 

 

定義 TPS 的粒度

  • 一般會根據場景的目的來定義 TPS 的粒度
  • 接口層性能測試:T 可以定義為接口級
  • 業務級性能測試:T 可以定義為每個業務步驟和完整的業務流

 

栗子

如果要單獨測試接口 1、2、3,那麼 T 就是接口級

如果從用戶角度下訂單,那 1、2、3 都在一個 T 中,就是業務級

結合實際業務設計,庫存服務一定是同步,而積分服務可以是異步,所以這個下單業務,可以只看作由 1、2 這兩個接口組成,但是 3 接口還是要監控分析的

 

所以,性能中 TPS 中 T 的定義取決於場景的目標和 T 的作用

 

拿上圖做個例子

接口級腳本

——事務 start(接口 1)

接口 1 腳本

——事務 end(接口 1)

——事務 start(接口 2)

接口 2 腳本

——事務 end(接口 2)

——事務 start(接口 3)

接口 3 腳本

——事務 end(接口 3)

 

業務級接口層腳本(就是用接口拼接出一個完整的業務流)

——事務 start(業務 A)

接口 1 腳本 – 接口 2(同步調用)

接口 1 腳本 – 接口 3(異步調用)

——事務 end(業務 A)

 

用戶級腳本

——事務 start(業務 A)

點擊 0 – 接口 1 腳本 – 接口 2(同步調用)

點擊 0 – 接口 1 腳本 – 接口 3(異步調用)

——事務 end(業務 A)

 

總結

一般情況下,我們會按從上到下的順序一一來測試,這樣路徑清晰地執行,容易定位問題

 

QPS(Queries per Second)

  • 每秒查詢率,在數據庫中每秒執行 SQL 數量
  • 一個請求可能會執行多條 SQL
  • 某些企業可能會用QPS代替TPS
  • 也是衡量服務端處理能力的一個指標,但不建議使用

 

RPS(Request per Second)

簡單理解

每秒請求數,用戶從客戶端發起的請求數

 

深入挖掘

對於請求數來說,也要看是哪個層面的請求,把上面的圖做一點點變化來描述請求數

如果一個用戶點擊了一次,發出來 3 個 HTTP Request,調用了 2 次訂單服務,調用了 2 次庫存服務,調用了 1 次積分服務

問:Request 數量如何計算

答:3+2+2+1 = 8?不, 應該是 3,因為發出了 3 個 Request,而調用服務會有單獨的描述,以便做性能統計

 

 

HPS(Hit per Second)

  • 點擊率,每秒點擊數
  • 有直接理解為用戶在界面上的點擊次數
  • 一般在性能測試中,都用來描述 HTTP Request,那它代表每秒發送 HTTP 請求的數量,和 RPS 概念完全一樣
  • HPS 越大對 Server 的壓力越大

 

CPS/CPM(Calls Per Second/ Calls Per Minutes)

  • 每秒/每分鐘調用次數
  • 通常用來描述 Service 層的單位時間內被其他服務調用的次數

 

栗子

上圖的訂單服務、庫存服務、積分服務,各調用了2、2、1次,還是比較好理解的

 

TPS、QPS、RPS、HPS、CPS 的總結

有很多維度可以衡量一個系統的性能能力,但是如果把五個指標同時都拿來描述系統性能能力的話,未必太混亂了

 

為此我們可以這樣做

  • TPS 來統一形容系統的性能能力,其他的都在各層面加上限制條件來描述,比如說:接口調用 1000 Calls/s
  • 在團隊中要定義清楚術語的使用場景,還有含義

 

吞吐量(Throughput)

單位時間內,網絡處理的請求數量(事務/s)

網絡沒有瓶頸時,吞吐量≈TPS

 

吞吐率

單位時間內,在網絡傳輸的數據量的平均速率(kB/s)

 

資源利用率

  • 服務器資源的使用程度,比如服務器(應用、服務器)的CPU利用率,內存利用率,磁盤利用率,網絡帶寬利用率
  • 一般不超過80%

 

結尾

本篇博文,部分參考了高老師的《性能測試實戰30講》,因為指標那一塊講的特別好哦~

 

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※教你寫出一流的銷售文案?

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※回頭車貨運收費標準

※別再煩惱如何寫文案,掌握八大原則!

※超省錢租車方案

※產品缺大量曝光嗎?你需要的是一流包裝設計!

.NETCore微服務探尋(一) – 網關

前言

一直以來對於.NETCore微服務相關的技術棧都處於一個淺嘗輒止的了解階段,在現實工作中也對於微服務也一直沒有使用的業務環境,所以一直也沒有整合過一個完整的基於.NETCore技術棧的微服務項目。正好由於最近剛好辭職,有了時間可以寫寫自己感興趣的東西,所以在此想把自己了解的微服務相關的概念和技術框架使用實現記錄在一個完整的工程中,由於本人技術有限,所以錯誤的地方希望大家指出。\

項目地址:https://github.com/yingpanwang/fordotnet/tree/dev

什麼是Api網關

  由於微服務把具體的業務分割成單獨的服務,所以如果直接將每個服務都與調用者直接,那麼維護起來將相當麻煩與頭疼,Api網關擔任的角色就是整合請求並按照路由規則轉發至服務的實例,並且由於所有所有請求都經過網關,那麼網關還可以承擔一系列宏觀的攔截功能,例如安全認證,日誌,熔斷

為什麼需要Api網關

 因為Api網關可以提供安全認證,日誌,熔斷相關的宏觀攔截的功能,也可以屏蔽多個下游服務的內部細節

有哪些有名的Api網關項目

  • Zuul Spring Cloud 集成
  • Kong 一款lua輕量級網關項目
  • Ocelot .NETCore網關項目

Ocelot使用

1.通過Nuget安裝Ocelot

2.準備並編輯Ocelot配置信息

Ocelot.json

{
  "ReRoutes": [
    // Auth
    {
      "UpstreamPathTemplate": "/auth/{action}", // 上游請求路徑模板
      "UpstreamHttpMethod": [ "GET", "POST", "PUT", "DELETE" ], // 上游請求方法
      "ServiceName": "Auth", // 服務名稱
      "UseServiceDiscovery": true, // 是否使用服務發現
      "DownstreamPathTemplate": "/connect/{action}", // 下游匹配路徑模板
      "DownstreamScheme": "http", // 下游請求
      "LoadBalancerOptions": { // 負載均衡配置
        "Type": "RoundRobin"
      }
      //,
      // 如果不採用服務發現需要指定下游host
      //"DownstreamHostAndPorts": [
      //  {
      //    "Host": "10.0.1.10",
      //    "Port": 5000
      //  },
      //  {
      //    "Host": "10.0.1.11",
      //    "Port": 5000
      //  }
      //]
    }
  ],
  "GlobalConfiguration": { // 全局配置信息
    "BaseUrl": "http://localhost:5000", // 請求 baseurl 
    "ServiceDiscoveryProvider": { //服務發現提供者
      "Host": "106.53.199.185",
      "Port": 8500,
      "Type": "Consul" // 使用Consul
    }
  }
}

3.添加Ocelot json文件到項目中

將Config目錄下的ocelot.json添加到項目中

4.在網關項目中 StartUp ConfigService中添加Ocelot的服務,在Configure中添加Ocelot的中間件(由於我這裏使用了Consul作為服務發現,所以需要添加Consul的依賴的服務AddConsul,如果不需要服務發現的話可以不用添加)

5.將需要發現的服務通過代碼在啟動時註冊到Consul中

我這裏自己封裝了一個註冊服務的擴展(寫的比較隨意沒有在意細節)

appsettings.json 中添加註冊服務配置信息

"ServiceOptions": {
    "ServiceIP": "localhost",
    "ServiceName": "Auth",
    "Port": 5800,
    "HealthCheckUrl": "/api/health",
    "ConsulOptions": {
      "Scheme": "http",
      "ConsulIP": "localhost",
      "Port": 8500
    }
  }

擴展代碼 ConsulExtensions(注意:3.1中 IApplicationLifetime已廢棄 所以使用的是IHostApplicationLifetime 作為程序生命周期注入的方式)


using Consul;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;

namespace ForDotNet.Common.Consul.Extensions
{
    /// <summary>
    /// 服務配置信息
    /// </summary>
    public class ServiceOptions
    {
        /// <summary>
        /// 服務ip
        /// </summary>
        public string ServiceIP { get; set; }

        /// <summary>
        /// 服務名稱
        /// </summary>
        public string ServiceName { get; set; }

        /// <summary>
        /// 協議類型http or https
        /// </summary>
        public string Scheme { get; set; } = "http";

        /// <summary>
        /// 端口
        /// </summary>
        public int Port { get; set; }

        /// <summary>
        /// 健康檢查接口
        /// </summary>
        public string HealthCheckUrl { get; set; } = "/api/values";

        /// <summary>
        /// 健康檢查間隔時間
        /// </summary>
        public int HealthCheckIntervalSecond { get; set; } = 10;

        /// <summary>
        /// consul配置信息
        /// </summary>
        public ConsulOptions ConsulOptions { get; set; }
    }

    /// <summary>
    /// consul配置信息
    /// </summary>
    public class ConsulOptions
    {
        /// <summary>
        /// consul ip
        /// </summary>
        public string ConsulIP { get; set; }

        /// <summary>
        /// consul 端口
        /// </summary>
        public int Port { get; set; }

        /// <summary>
        /// 協議類型http or https
        /// </summary>
        public string Scheme { get; set; } = "http";
    }

    /// <summary>
    /// consul註冊客戶端信息
    /// </summary>
    public class ConsulClientInfo
    {
        /// <summary>
        /// 註冊信息
        /// </summary>
        public AgentServiceRegistration RegisterInfo { get; set; }

        /// <summary>
        /// consul客戶端
        /// </summary>
        public ConsulClient Client { get; set; }
    }

    /// <summary>
    /// consul擴展(通過配置文件配置)
    /// </summary>
    public static class ConsulExtensions
    {
        private static readonly ServiceOptions serviceOptions = new ServiceOptions();

        /// <summary>
        /// 添加consul
        /// </summary>
        public static void AddConsulServiceDiscovery(this IServiceCollection services)
        {
            var config = services.BuildServiceProvider().GetService<IConfiguration>();
            config.GetSection("ServiceOptions").Bind(serviceOptions);
            //config.Bind(serviceOptions);

            if (serviceOptions == null)
            {
                throw new Exception("獲取服務註冊信息失敗!請檢查配置信息是否正確!");
            }
            Register(services);
        }

        /// <summary>
        /// 添加consul(通過配置opt對象配置)
        /// </summary>
        /// <param name="app"></param>
        /// <param name="life">引用生命周期</param>
        /// <param name="options">配置參數</param>
        public static void AddConsulServiceDiscovery(this IServiceCollection services, Action<ServiceOptions> options)
        {
            options.Invoke(serviceOptions);
            Register(services);
        }

        /// <summary>
        /// 註冊consul服務發現
        /// </summary>
        /// <param name="app"></param>
        /// <param name="life"></param>
        public static void UseConsulServiceDiscovery(this IApplicationBuilder app, IHostApplicationLifetime life)
        {
            var consulClientInfo = app.ApplicationServices.GetRequiredService<ConsulClientInfo>();
            if (consulClientInfo != null)
            {
                life.ApplicationStarted.Register( () =>
                {
                     consulClientInfo.Client.Agent.ServiceRegister(consulClientInfo.RegisterInfo).Wait();
                });

                life.ApplicationStopping.Register( () =>
                {
                     consulClientInfo.Client.Agent.ServiceDeregister(consulClientInfo.RegisterInfo.ID).Wait();
                });
            }
            else
            {
                throw new NullReferenceException("未找到相關consul客戶端信息!");
            }
        }

        private static void Register(this IServiceCollection services)
        {
            if (serviceOptions == null)
            {
                throw new Exception("獲取服務註冊信息失敗!請檢查配置信息是否正確!");
            }
            if (serviceOptions.ConsulOptions == null)
            {
                throw new ArgumentNullException("請檢查是否配置Consul信息!");
            }

            string consulAddress = $"{serviceOptions.ConsulOptions.Scheme}://{serviceOptions.ConsulOptions.ConsulIP}:{serviceOptions.ConsulOptions.Port}";

            var consulClient = new ConsulClient(opt =>
            {
                opt.Address = new Uri(consulAddress);
            });

            var httpCheck = new AgentServiceCheck()
            {
                DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(10), // 服務啟動多久后註冊
                Interval = TimeSpan.FromSeconds(serviceOptions.HealthCheckIntervalSecond), // 間隔
                HTTP = $"{serviceOptions.Scheme}://{serviceOptions.ServiceIP}:{serviceOptions.Port}{serviceOptions.HealthCheckUrl}",
                Timeout = TimeSpan.FromSeconds(10)
            };

            var registration = new AgentServiceRegistration()
            {
                Checks = new[] { httpCheck },
                ID = Guid.NewGuid().ToString(),
                Name = serviceOptions.ServiceName,
                Address = serviceOptions.ServiceIP,
                Port = serviceOptions.Port,
            };

            services.AddSingleton(new ConsulClientInfo()
            {
                Client = consulClient,
                RegisterInfo = registration
            });
        }
    }
}

6.啟動運行

  • 啟動consul
  • 啟動 Auth,Gateway項目
  • 通過網關項目訪問Auth

啟動Consul

為了方便演示這裡是以開發者啟動的consul
在consul.exe的目錄下執行
consul agent -dev -ui // 開發者模式運行帶ui

啟動 Auth,Gateway項目

啟動項目和可以發現我的們Auth服務已經註冊進來了

通過網關訪問Auth

我們這裏訪問 http://localhost:5000/auth/token 獲取token

我們可以看到網關項目接收到了請求並在控制台中打印出以下信息

然後在Auth項目中的控制台中可以看到已經成功接收到了請求並響應

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※超省錢租車方案

※別再煩惱如何寫文案,掌握八大原則!

※回頭車貨運收費標準

※教你寫出一流的銷售文案?

※產品缺大量曝光嗎?你需要的是一流包裝設計!

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

加拿大減塑 2021年底前禁六大類一次性塑膠製品

摘錄自2020年10月8日中央社報導

加拿大環境部長今(7日)宣布,2021年底之前,加拿大將禁用塑膠袋、塑膠吸管等一次性塑膠用品;他也坦言,加國在回收方面落後歐洲。

今天公布的禁令另將涵蓋攪拌棒、啤酒提環、餐盤以及難以回收的塑膠製餐具,是總理杜魯道(Justin Trudeau)放眼2030年前消滅塑膠垃圾,兌現氣候與環境政見核心的計畫一環。

但環境部長威金森(Jonathan Wilkinson)坦言:「我們這方面不在世界的前段班。」

政府表示,加拿大人每年丟棄300萬公噸塑膠垃圾,其中包括一年丟棄150億個塑膠袋、每天丟掉5700萬支塑膠吸管,在這之中,僅有9%回收。

污染治理
國際新聞
加拿大
一次性塑膠製品
禁塑
塑膠垃圾
一次性塑膠袋

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※Google地圖已可更新顯示潭子電動車充電站設置地點!!

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※別再煩惱如何寫文案,掌握八大原則!

網頁設計最專業,超強功能平台可客製化

瑞典船運業推出「海洋鳥」 以風為動力可遠洋運輸

摘錄自2020年9月24日科技新報報導

瑞典造船公司 Wallenius Marine 近日宣布推出以風為主要動力、全新的遠洋運輸船「海洋鳥」(Oceanbird),盼開啟環保航運新的一頁。

由於海洋鳥上的機翼帆採取伸縮式結構,當通過橋下或遭遇強風時便能迅速縮小帆體的表面積來進行控制,船體同時也配備輔助的綠能引擎,做為進出港口使用的安全措施。

由於使用風能為主要航行動力,海洋鳥的航行速度較傳統貨輪來的慢,僅能以約 10 節的平均速度航行,橫渡北大西洋約需要 12 天的時間,但在不需要使用高污染燃油下,海洋鳥可以減少近 90% 的排放。

在瑞典運輸署的支持下,Wallenius 已經建造出海洋鳥的小型模型,將於接下來幾個月進行測試,預計完整設計明年底前將準備就緒,2025 年首艘船將正式登場。

能源轉型
國際新聞
瑞典
航運
海運

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※想知道最厲害的網頁設計公司"嚨底家"!

※別再煩惱如何寫文案,掌握八大原則!

※產品缺大量曝光嗎?你需要的是一流包裝設計!

疫情肆虐下 日本民眾提高對太陽能板裝設興趣

文:宋瑞文(加州能源特約撰述)

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※別再煩惱如何寫文案,掌握八大原則!

※教你寫出一流的銷售文案?

※超省錢租車方案

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※產品缺大量曝光嗎?你需要的是一流包裝設計!

印尼就業環保新法救經濟 勞工抗議延燒

摘錄自2020年10月7日中央社報導

疫情重創經濟,印尼政府加速鬆綁勞動及環保法規,日前突襲通過新法,盼改善投資環境增加就業機會,卻引發大規模抗議,遭質疑修法犧牲勞工權益及環保,爭議恐持續延燒。

印尼政府年初提出創造就業綜合法案後,民間抗議聲浪不斷,勞工團體多次上街表達不滿。

印尼國會5日趕在全國性大罷工前夕審查完法案。印尼請願網站當天發起拒絕創造就業綜合法案的連署迅速累積逾120萬人支持,各大城市爆發罷工示威潮。

在國會審議前,印尼總統佐科威(Joko Widodo)重要幕僚、海洋事務統籌部長盧胡特(Luhut Panjaitan)指出,政府因處理武漢肺炎疫情,這項法案自4月延宕至今。該法案是促進投資的關鍵,幾經協商,全國8大主要工會組織中有6大工會組織同意立法。

不過,由印尼工會聯盟(KSPI)、印尼工人工會聯合會(KSPSI)等團體發動的罷工6日在各大城市許多工業區吸引成千上萬勞工參與。

除了勞動法規,創造就業綜合法案通過也影響環保及稅務等超過70個法律,主要目的是降低投資障礙,方便投資者取得土地及相關證照。這部分引起環保團憂心將弱化環境影響評估的把關機制,不利環境永續發展。

印尼綠色和平資深森林專員亞塞普(Asep Komarudin)7日對中央社指出,現行法規有很多嚴格確保環境保護的條文都因創造就業綜合法案通過而遭廢除,例如未來有些投資案可不經環境影響評估,環評也將限制只有受影響者才參與,不再開放公民參與。

亞塞普說,根據創造就業綜合法案,未來開發案與環保衝突時,被視為與國家策略發展相關的計畫都要給予優先考量,主導開發的國家與企業肯定會持續與原住民族發生衝突,巴布亞(Papua)、加里曼丹(Kalimantan)、蘇門答臘(Sumatra)等地的林地面積可能會再減少3成以上,「我們非常擔心」。

國際新聞
印尼
修法
環保法
勞工剝削
抗議

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※別再煩惱如何寫文案,掌握八大原則!

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※超省錢租車方案

※教你寫出一流的銷售文案?

網頁設計最專業,超強功能平台可客製化

※產品缺大量曝光嗎?你需要的是一流包裝設計!

等同666個台灣 南極臭氧層破洞創近年「最大最深」

摘錄自2020年10月7日自由時報報導

聯合國世界氣象組織(WMO)宣布,南極臭氧層破洞已經創下近年來的「最大最深」,破洞於8月中旬起迅速變大,10月初面積達2400萬平方公里,以台灣面積為3.6萬平方公里來看,相當於666個台灣。

根據美國《ABC新聞》報導,聯合國世界氣象組織指出,目前出現在南極上空的破洞是近幾年來「最大」和「最深」的,強烈的極地渦流是此次臭氧層的導火線,負78度的極度低溫條件下形成「極地平流層雲」,雲中含有冰晶,經太陽光照射後就會產生化學反應,開始大量消耗臭氧。

美國太空總署表示,異常的南極天氣是造成這種情況的原因;歐洲中期天氣預報中心哥白尼大氣監測局局長佩奇(Vincent-Henri Peuch)認為,每年發生的南極臭氧層破洞事件都有很大的差異,這也表明人們需要持續減少排放有害物質,繼續執行《蒙特婁議定書》的規範事項。

氣候變遷
國際新聞
南極
南極臭氧層

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※教你寫出一流的銷售文案?

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※回頭車貨運收費標準

※別再煩惱如何寫文案,掌握八大原則!

※超省錢租車方案

※產品缺大量曝光嗎?你需要的是一流包裝設計!

受農藥所苦的「空中王者」 柬埔寨三種瀕危兀鷲數量持續下降

環境資訊中心綜合外電;黃鈺婷 編譯;林大利 審校

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※超省錢租車方案

※別再煩惱如何寫文案,掌握八大原則!

※回頭車貨運收費標準

※教你寫出一流的銷售文案?

※產品缺大量曝光嗎?你需要的是一流包裝設計!

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

15萬買啥車?有轎車有SUV,這2款合資車可以放心買

勁客的優勢在於成熟可靠的動力總成,採用1。5L自然吸氣發動機+CVT無級變速器的搭配能夠帶來非常平順線性的輸出,油門調校靈敏,能夠很好地應付日常市區內行駛,並且也非常省油,可靠性較高。不過其檔次感與配置水平不如哈弗H2。

15萬左右比較推薦的是本田XR-V與豐田卡羅拉,這兩款車目前在市場上都有着不錯的銷量、保值率以及口碑,XR-V在小型SUV市場混得風生水起,靠的就是其成熟的動力系統和越級的空間表現,家用是個非常棒的選擇。而卡羅拉乃全球銷量神車,中庸就是其最大的武器,除了汽油版本外還有雙擎版本可選,擁有非常優秀的燃油經濟性,能夠滿足許許多多的消費者,除了隔音濾振差點,其它方面的表現都非常不錯,乃家用車的不二之選。

一輛是接近中型車的緊湊型車,一輛是標準的中型車,凌渡280DSG豪華版擁有更加豐富的配置,不過因為其比較扁平的設計所以頭部空間表現一般,而君威中型車的身份自然擁有更大的空間以及更高的檔次感,同時全系標配9AT也讓其競爭力進一步上升,採用的1.5T發動機也有着不錯的動力輸出,因此更推薦君威1.5T中配。

510採用的是6擋手動變速器和5擋AMT變速器,假設會開手動擋的話更加推薦手動車型,6個擋位在高速行駛時把轉速壓得更低,能帶來更好的燃油經濟性,同時擁有更高的傳動效率及可靠性,510的手動擋換擋手感不錯,有吸入感並且行程不長,離合器的力度也不沉,沒那麼容易疲勞。而AMT變速器雖然說省去了踩離合器的麻煩,但是其換擋邏輯不清晰,而且頓挫比較嚴重,尤其是在起步階段或者是在堵車狀況下,因此更加推薦510的手動版車型。

兩車都是定位小型SUV,哈弗H2擁有更加親民的售價,更加大氣上檔次的外觀內飾設計,同時配置更加豐富,採用的1.5T發動機+7擋雙離合的搭配,擁有不錯的爆發力,但是雙離合變速器的邏輯有待提高,並且油耗也會偏高。

勁客的優勢在於成熟可靠的動力總成,採用1.5L自然吸氣發動機+CVT無級變速器的搭配能夠帶來非常平順線性的輸出,油門調校靈敏,能夠很好地應付日常市區內行駛,並且也非常省油,可靠性較高。不過其檔次感與配置水平不如哈弗H2。

綜上,假如你預算充足的話,更加建議購買勁客的中配以上車型,而預算不是很足的話,那麼家用選擇H2是一個非常具有性價比的選擇。

2018款飛度新增了運動套件車型,不過在配置方面還是一如既往的寒酸,比較推薦指導價為8.88萬的1.5L CVT潮跑版,在配置上面擁有主/副駕駛座安全氣囊、運動外觀套件、行車電腦显示屏、前霧燈等,類似比較常用的电子車身穩定系統、駐車雷達要到頂配才配備,但是飛度的動力和空間還是非常不錯的,1.5L自吸發動機就能爆發出131匹馬力,日常市區駕駛毫無壓力,加上本田“MM”理念,讓它的空間能夠滿足大多數人的使用需求,市面上大量的改裝件也能讓每位飛度車主把愛車改成獨一無二的樣子。

以上就是本期網友問答欄目的全部內容,假如你也想上牆的話,點擊下方留言留下你的問題並且點個贊,就有機會在下期欄目看見你的身影!本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※Google地圖已可更新顯示潭子電動車充電站設置地點!!

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※別再煩惱如何寫文案,掌握八大原則!

網頁設計最專業,超強功能平台可客製化

Node.js躬行記(4)——自建前端監控系統

  這套前端監控系統用到的技術棧是:React+MongoDB+Node.js+Koa2。將性能和錯誤量化。因為自己平時喜歡吃菠蘿,所以就取名叫菠蘿系統。其實在很早以前就有這個想法,當時已經實現了前端的參數搜集,只是後台遲遲沒有動手,也就拖着。

  • 目前完成的還只是個雛形,僅僅是搜集了錯誤和相關的性能參數。

  • 後台樣式採用了封裝過的matrix。

  • 分析功能還很薄弱,只是做了簡單的演示,並且各種基礎功能還有待完善。

  • 後面打算強化數據分析,並且還要實現錯誤的回放機制,思路的話以前也調研過,參考之前的一篇文章

  現在的這個系統還只能算是個玩具,後期還需要雕琢雕琢。下面是這套系統的目錄結構。

├── pingapple --------------------------------- 菠蘿監控系統
│   ├── client -------------------------------- 系統的前端部分
│   ├── sdk ----------------------------------- 信息搜集代碼庫
│   ├── server -------------------------------- 系統的後端部分

一、SDK

1)primus.js

  在之前的《前端頁面性能參數搜集》一文中,詳細記載了各類性能指標的計算規則,並整理到了primus.js中。

  本次將在primus.js的基礎上做適當的修改,包括刪除代理、測速、資源信息等功能,改變部分性能指標的計算規則,例如從瀏覽器發起HTTP請求算起,忽略瀏覽器重定向的時間等。

2)錯誤處理

  完善錯誤處理,將錯誤分成三類:runtime、load和Promise。在window的error事件中,處理前兩種錯誤。像img元素載入的圖片地址不存在,就會執行formatLoadError()函數;像變量未定義,就會執行formatRuntimerError()函數。

window.addEventListener("error", function (event) {
    var errorTarget = event.target;
    // 過濾 target 為 window 的異常
    if (
      errorTarget !== window &&
      errorTarget.nodeName &&
      LOAD_ERROR_TYPE[errorTarget.nodeName.toUpperCase()]
    ) {
      handleError(formatLoadError(errorTarget));
    } else {
      handleError(
        formatRuntimerError(
          event.message,
          event.filename,
          event.lineno,
          event.colno,
          event.error
        )
      );
    }
  }, true
);

  將window綁定unhandledrejection事件后,就會在Promise被拒絕且沒有reject的回調函數時觸發。

window.addEventListener(
  "unhandledrejection",
  function (event) {
    // console.log('Unhandled Rejection at:', event.promise, 'reason:', event.reason);
    handleError({
      type: ERROR_PROMISE,
      desc: event.reason,
      stack: "no stack"
    });
  },
  true
);

3)初始化

  由於要計算白屏時間,DOM時間等,所以位置不能隨便放,得要放在head的最後面。

<head>
  <script>
    window.pineapple || (pineapple = {});
    pineapple.param = {
      "token": "dsadasd2323dsad23dsada"
    };
  </script>
  <script src="js/pineapple.js"></script>
</head>

二、服務端

1)Koa

  Koa是由Express原班人馬打造的Web輕量框架,通過組合各種中間件來避免繁瑣的回調函數嵌套,當前使用的版本是V2。

npm install --save koa

  使用的Koa腳手架:koa-generator,創建項目的結構,並且在此基礎上做了調整(目錄如下所示)。暫時還不會用到靜態資源和視圖層。

npm install -g koa-generator
├── server --------------------------------- 服務端
│   ├── bin -------------------------------- 命令
│   ├── config ----------------------------- 配置目錄
│   ├── controllers ------------------------ MVC中的邏輯層
│   ├── db --------------------------------- MVC中的數據層
│   ├── public ----------------------------- 靜態資源
│   ├── routes ----------------------------- 路由
│   ├── utils ------------------------------ 工具庫
│   ├── views ------------------------------ MVC中的視圖層
│   ├── app.js ----------------------------- 入口文件

  為了區分開發環境和生產環境,通過cross-env統一不同系統設置環境變量的方式。

npm install --save cross-env

  package.json中的命令如下,添加了環境配置。

"scripts": {
  "start": "node bin/www",
  "dev": "cross-env NODE_ENV=development ./node_modules/.bin/nodemon bin/www",
  "prd": "cross-env NODE_ENV=production pm2 start bin/www"
}

  prd按字面意思應該是生產環境的命令,其中使用了pm2,默認沒有安裝。還沒部署過Node.js,還不清楚裏面有多少坑。

npm install --save pm2

2)MongoDB

  MongoDB是一個開源的非關係型數據庫(圖1是下載界面),既沒有表、行等概念,也沒有固定的模式和結構,所有的數據以文檔(一個對象)的形式存儲。但其使用方式和關係型數據庫相似,並且還支持對數據建立索引,適用於高併發讀寫、海量數據存儲和實時分析等。

圖1

  注意,在安裝時默認會下載MongoDB Compress(一個可視化的MongoDB工具),默認下載會非常慢,建議自行下載,該工具的界面還是蠻清爽的,如圖2所示。

圖2

  在Mac上配置MongoDB比較麻煩,不像Windows那樣一件安裝,需要一些步驟,廢了點力氣才裝好,下面是執行的命令。

sudo mongod --dbpath=/Users/pw/data

3)Mongoose

  Mongoose是MongoDB的一個ORM(Object-Document Mapper,對象文檔映射)工具,可在Node.js環境中執行,封裝了MongoDB操作文檔的常用方法,包括引入數據庫連接(connect),定義模型(model),聲明文檔結構(scheme),實例化模型等操作數據庫的方法。

npm install --save mongoose

  借鑒了以前PHP數據分層的思想,單獨分離出數據庫的連接,並抽象通用的Model層(如下所示)。

const mongoose = require("./db");
class Mongodb {
  constructor(name, schema) {
    //聲明結構
    const mySchema = new mongoose.Schema(schema, { typeKey: "$type" });
    this.model = mongoose.model(name, mySchema);
  }
  //保存
  save(obj) {
    obj.created = Date.now();         //日期
    const doc = new this.model(obj);
    return new Promise((resolve, reject) => {
      doc.save((err, row) => {
        if (err) {
          reject(err);
          return;
        }
        resolve(row);
      });
    });
  }
}
module.exports = {
  model: Mongodb,
  mongoose
};

4)路由

  由於發送的地址是一張gif圖片,因此在處理路由時,返回本地的一張gif圖,如下所示,圖像地址得是絕對路徑,否則無法讀取。

router.get('/pa.gif', async (ctx, next) => {
  const ctr = new indexController();
  ctr.collect(ctx);
  const url = path.resolve(__dirname, "../public/images/blank.gif");
  ctx.body = fs.readFileSync(url);    //空白gif圖
});

5)代理分析

  在接收參數的時候分析代理所帶的信息,例如瀏覽器、操作系統、設備等。使用的是一個第三方庫:UAParser.js,四年前就關注過,當時GitHub上只有1K多個關注量,現在已經翻了4倍。

npm install --save ua-parser-js

6)假數據

  製作一套合適的假數據,新增命令“npm run data”,初始化數據,便於展示。

三、後台

1)UI

  後台模板採用了之前封裝過的Matrix,但不會依賴Bootstrap框架。

  將整個頁面分成五塊,分別是導航、側邊欄、麵包屑、底部欄以及主體。

  安裝react-router的history,用於路由。

npm install --save history

  期間也會安裝各類依賴包,例如不支持在類中直接聲明屬性等。

  在使用的過程中,ESLint會不時的彈出各種錯誤和警告,期間就不停的修改問題或查找相關配置忽略部分限制。

  後台的側邊欄和麵包屑等部分,會隨着URL的不同而發生狀態變化,本來想用多頁實現,但配置要改很多,就依然做成一個SPA,只是稍微做了些改動。

  組件庫採用了流行的Ant Design,調用了按鈕、單選框、日期等組件。

npm install --save antd

  圖表庫使用的是ECharts,目前只用到了折線圖和餅圖。在引用圖表時,為了優化構建,採取了按需引用的手段。

npm install --save echarts

2)項目管理

  首先建立一個項目,然後才能分析該項目的性能和錯誤,如圖3所示。

圖3

  用彈框的形式來創建項目,使用了Ant Design的Model、Form等組件,如圖4所示。

圖4

3)性能分析

  在第一個折線圖標籤中的過濾條件包括項目、字段、日期等,性能指標按平均值呈現,可看到每個性能指標的趨勢,如圖5所示。

圖5

  按分時日統計性能平均數,在MongoDB中計算。原先創建日期是以時間戳的形式存儲的,為了便於使用Aggregate,改成字符串形式。碰到一個坑,MongoDB中的Date類型採用的是格林尼治時間,而不是當前時區的時間,也就是說存在數據庫中的時間會比當前時間早8小時。

  在第二個列表標籤中,可以詳細看到每條記錄的信息,包括代理、網絡等,便於在了解趨勢的前提下,獲悉更為細節的內容,如圖6所示。

圖6

  點擊ajax那一列,可彈出具體的異步請求信息,如圖7所示。

圖7

4)錯誤分析

  有三個標籤,第一個也是折線圖,描繪的是某個時間的錯誤個數;第二個是錯誤列表,會給出具體的錯誤信息,如圖8所示。

圖8

  第三個是餅圖,餅圖主要體現的是發生錯誤的瀏覽器分佈情況(如圖9所示),點擊某一塊可查看瀏覽器的具體版本(如圖10所示)。

圖9

圖10

 

 

【參考資料】
PerformanceTiming

unhandledrejection 處理沒有顯式捕獲的 Promise 異常

狼書(卷2)

Node-區分環境

Koa從零搭建到Api實現—項目部署

koa如何連接MongoDB

Koa2進階學習筆記

如何計算首屏加載時間 

Mongoose Schema Error: “Cast to string failed for value” when pushing object to empty array

Support for the experimental syntax ‘classProperties’ isn’t currently enabled

Template string failing with Cannot read property ‘range’ of null

Disallow JSX props spreading (react/jsx-props-no-spreading)

TypeError: Cannot read property ‘range’ of null from template-curly-spacing

echarts項目的優化

使用 happypack 提升 Webpack 項目構建速度

mac下的mongoDB的安裝和啟動

安裝MongoDB報錯 mkdir: /data/db: Read-only file system

$sum mongoose

 

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※Google地圖已可更新顯示潭子電動車充電站設置地點!!

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※別再煩惱如何寫文案,掌握八大原則!

網頁設計最專業,超強功能平台可客製化