疑似 iPad mini 6 渲覽圖現身!採相機挖孔、螢幕下 Touch ID 技術_貨運

※回頭車貨運收費標準

宇安交通關係企業,自成立迄今,即秉持著「以誠待人」、「以實處事」的企業信念

除了 iPad Pro,新一代 iPad mini 系列也是很多人非常感興趣的新品,去年 Apple 沒有更新,因此今年就蠻有機會的,而就在稍早國外出現一組疑似 iPad mini 6 的渲染圖,不僅顯示螢幕邊框變更窄,還採螢幕下 Touch ID 與鏡頭(挖孔)設計,感覺超級讚。

疑似 iPad mini 6 渲覽圖現身

稍早外媒 Pigtou 分享一組 Apple iPad mini 6 的渲染圖,外觀跟現行的 iPad mini 5 有非常大不同,甚至用大躍進來形容也不為過。

螢幕部分邊框大幅變窄,佔比變更高,看起來有點類似 2020 iPad Pro,但正面自拍鏡頭變成嵌在螢幕下方,如果真是這樣,那 iPad mini 6 應該是目前首款採用這類面板的 Apple 行動裝置產品:

此外,iPad mini 6 圖片下方也顯示,這款會採用螢幕下指紋辨識技術,就跟謠傳的 iPhone 13 一樣,這點相信很多人也非常樂見。

尺寸部分,目前獲得的資訊是 203.2mm(長)x 134.8mm(寬)x 6.25mm(厚度),螢幕大約為 195mm x 126.6mm,根據他們計算,大約是 9.15 吋,這我就覺得怪怪的,iPad mini 的定位應該是小尺寸平版,iPad mini 5 也僅 7.9 吋,iPad mini 6 一下變到 9.15 吋,這幅度似乎有點太大。

※智慧手機時代的來臨,RWD網頁設計為架站首選

網動結合了許多網際網路業界的菁英共同研發簡單易操作的架站工具,及時性的更新,為客戶創造出更多的網路商機。

其餘硬體規格 Pigtou 就沒有說明,不過 iPad Air 4 搭載 A14 Bionic 晶片,iPad mini 6 也有很大機會使用相同的晶片。推出時間有可能會落在三月份,如果這渲染圖是真的,那應該下個月有機會看到實機間諜圖現身,我們也會隨時追蹤。

話說回來,iPad mini 6 假設真的變成這種設計(螢幕下鏡頭 + Touch ID),那價格我猜一定會提升不少。

資料來源:Pigtou

您也許會喜歡:

【推爆】終身$0月租 打電話只要1元/分

立達合法徵信社-讓您安心的選擇

※評比南投搬家公司費用收費行情懶人包大公開

搬家價格與搬家費用透明合理,不亂收費。本公司提供下列三種搬家計費方案,由資深專業組長到府估價,替客戶量身規劃選擇最經濟節省的計費方式

POCO M3 正式在台發表:6000mAh 超大電量、4800 萬像素 AI 三鏡頭主相機、立體聲揚聲器,售價只要 3,999 元起_網頁設計公司

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

透過選單樣式的調整、圖片的縮放比例、文字的放大及段落的排版對應來給使用者最佳的瀏覽體驗,所以不用擔心有手機版網站兩個後台的問題,而視覺效果也是透過我們前端設計師優秀的空間比例設計,不會因為畫面變大變小而影響到整體視覺的美感。

在 2018 年小米 POCO F1 在台灣市場推出後,以極致的性價比讓許多米粉相當期待,接下來 POCO 還會帶來哪些新機。隨著 2020 年 11 月 POCO 正式成為獨立品牌後,也終於在今(21)日稍早正式在台灣推出 POCO 品牌獨立後首款在台灣市場上市的智慧型手機「POCO M3」。

POCO M3 正式在台發表:6000mAh 超大電量、4800 萬像素 AI 三鏡頭主相機、立體聲揚聲器,售價只要 3,999 元起

台灣消費者許久未見到的 POCO 終於回來啦!今(21)日 POCO 終於推出品牌獨立後第一款產品「POCO M3」,狹帶著超越同價位的搭載 Qualcomm Snapdragon 662 行動平台、 6,000mAh 超大電量電池、 4800 萬像素 AI 三鏡頭主相機和立體聲揚聲器。外觀方面, POCO M3 在台灣推出「活力黃」、「冷酷藍」以及「動力黑」共三款配色。

 

開箱也幫大家準備好了,快來看看吧!(請點我)

螢幕方面, POCO M3 採用 6.53 吋 FHD+ (2340×1080)高解析度水滴全螢幕, 19.5:9 的螢幕比例與 90.34% 的高螢幕占比,提供更好的影音娛樂體驗。螢幕也通過德國萊因TÜV低藍光認證,即便長時間觀看手機也不易感到眼睛疲勞。螢幕採用康寧第三代大猩猩玻璃保護。

除了支援 AI 臉人臉解鎖,搭配結合側邊指紋辨識讓單手解鎖更加容易。

音效方面, POCO M3 內建立體聲雙喇叭和等效 0.76cc 的大音腔,擁有媲美旗艦機的高品質立體音效。

電量方面, POCO M3 配備 6,000mAh 高充電循環電池,擁有 24 天的超長待機時間;在聆聽音樂可使用連續約 8 天;觀看影片也能連續播放長達 17 小時,對於重度手機使用者更能滿足需求。 POCO M3 即便內建 6,000mAh 的超大電量電池,機身重量也控制在 198g 。
另外, POCO M3 支持最高18W快速充電,並標配 22.5W 快速充電器,提供高效的充電速度。此外, POCO M3 採用特製的高充電循環電池也更持久、耐用,高達 1,000 次電池循環充電次數,電池壽命在高溫環境相較其他手機提高 20% 。

相機部份, POCO M3 搭載 4800 萬像素 AI 三鏡頭主相機,包含 4800 萬像素 f/1.79 光圈主鏡頭、200 萬像素微距鏡頭以及 200 萬像素景深鏡頭的搭配,前置相機則為 800 萬像素自拍鏡頭。

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

節能減碳愛地球是景泰電動車的理念,是創立景泰電動車行的初衷,滿意態度更是服務客戶的最高品質,我們的成長來自於你的推薦。

銷售資訊

POCO M3 在台灣推出兩種規格選擇,售價分別為 4GB+64GB 版本建議售價 NT$3,999 、4GB+128GB 版本建議售價 NT$4,699 ,將於 1 月 22 日上午 10:00 起於 PChome24h 購物 POCO 品牌館獨家開賣。
首 2,000 名於 PChome24h 購物購買 POCO M3 並成功付款的消費者,將可獲贈「Redmi 行動電源 10000 標準版(價值 NT$345)」乙個(贈品數量有限,送完為止)。

POCO M3 直播專屬 NT$200 優惠碼:「YEAHPOCO」,可提前前往 PChome 24h 購物頁面完成登錄,使用名額有限、依完成結帳順序為準,用完為止(限量 500 名):點我前往

POCO Taiwan Facebook 粉絲專頁:點我前往
PChome2h 購物 POCO 品牌館:點我前往

開箱也幫大家準備好了,快來看看吧!(請點我)

POCO M3 開箱、評測|6000mAh 大電量超乎想像,極致性價比王者重返台灣市場

您也許會喜歡:

【推爆】終身$0月租 打電話只要1元/分

立達合法徵信社-讓您安心的選擇

南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

搬家費用:依消費者運送距離、搬運樓層、有無電梯、步行距離、特殊地形、超重物品等計價因素後,評估每車次單

外媒公布最佳 5 大分類 CPU 處理器推薦名單(全能、遊戲、生產力等)_包裝設計

南投搬家公司費用需注意的眉眉角角,別等搬了再說!

上新台中搬家公司提供您一套專業有效率且人性化的辦公室搬遷、公司行號搬家及工廠遷廠的搬家服務

升級 CPU 處理器時,雖然價格越貴效能絕對是越好,但並不是每個人都預算無上限,而且需求也不一樣,有些人主要是為了玩遊戲、也有些人生產力居多,甚至是想要找各方面表現都不錯的處理器。為此,近日知名硬體外媒就公布目前最佳 CPU 處理器名單,從全能、遊戲、頂級、到生產力都有,應該可以提供你不錯參考。

最佳 5 大分類 CPU 處理器推薦名單

下方是外媒 TECHSPOT 公布的前 5 名最佳 CPU 處理器名單,另外他們也提醒,對於不急的人來說,其實可以先等等,因為三月 Intel 很可能會推出第 11 代 Rocket Lake 處理器,到時排名有可能會變動。

最佳全能 CPU 處理器

  • 獲選的是「Ryzen 5 3600 或 Core i5-10400F」

TECHSPOT 表示,Ryzen 5 3600 會是最佳選擇,但如果你不喜歡 AMD CPU,則可以考慮 i5-10400F,這兩顆的品質與價格都非常不錯,因此可以大幅降低組裝成本。除此之外,幾個月前 Ryzen 5 3600  還是 Amazon 銷售排名第一,至今仍然相當暢銷。

最佳遊戲 CPU 處理器

  • 獲選的是「i9-10900K、10700K 或 Ryzen 9 5900X」

對於追求最佳遊戲效能 CPU 的人,則可以把範圍縮小到 Ryzen 7 5800X、Ryzen 9 5900X 與 5950X,或Core i7-10700K 與 Core i9-10900K,這幾顆的遊戲效能都差不多,不過多數遊戲都不需要超過 8 核心,因此最有價值的選擇會是 Ryzen 7 5800X 或 i7-10700K。

另外有些人可能會想說,Ryzen 7 5800X 並沒有獲選,為什麼他們推薦?這是因為 Ryzen 9 5900X 就技術來說更有價值,但如果只是為了玩遊戲,選 5900X 似乎有點浪費錢。

最佳頂級桌上型 CPU 處理器

  • 獲選的是「AMD Ryzen Threadripper 3990X」

這不讓人意外,TECHSPOT 稱 AMD Ryzen Threadripper 3990X 是一個野獸,高達 64 核心、128 執行緒的規格,效能不容懷疑,但價格當然也非常不便宜。

如果你覺得這顆太貴,Threadripper 3970X 或 3960X 也是不錯,近一年的時間他們都用 3960X 處理器當作主要遊戲、影片編輯的處理器,體驗一直都很棒。

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

窩窩觸角包含自媒體、自有平台及其他國家營銷業務等,多角化經營並具有國際觀的永續理念。

最佳生產力 CPU 處理器

  • 獲選的是「AMD Ryzen 9 5900X 或 5950X」

想要有最佳生產力的用戶,Ryzen 9 5900X 或 5950X 絕對是最佳選擇,價格分別為 550 美元與 800 美元,不過長期都處於缺貨狀態,因此無法等待的人,替代方案可改上一代的 3900X / 3950X 或 i9-10900K。

最佳預算內 CPU 處理器

  • 獲選的是「Intel i3-10100」

過去 TECHSPOT  都推薦 Ryzen 3 3300X,但自從 2020 年中之後就買不到,都沒補貨,因此才改推 Intel 這顆 i3-10100,遊戲效能跟比較貴的 Ryzen 5 1600 AF 相當,而且長期都能買到,這點比 AMD 出色。

另外有多一點預算,想要有效能不差內顯的處理器,Ryzen 5 3400G 仍然是最佳選擇。

結論

從以上名單可以明顯看出,就生產力來說,TECHSPOT 大多都推薦 AMD 處理器,畢竟核心與執行緒數量較多,但遊戲部分就 Intel 稍微強一點。所有推薦處理器 TECHSPOT 都有進行實測報告,有興趣閱讀的人,可以點我至 TECHSPOT 網站查看。

資料來源:TECHSPOT

國外零售商洩漏 Intel 第 11 代 Rocket Lake-S 處理器的售價,i9-11900K 價格比上一代便宜一些

您也許會喜歡:

【推爆】終身$0月租 打電話只要1元/分

立達合法徵信社-讓您安心的選擇

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

網動廣告出品的網頁設計,採用精簡與質感的CSS語法,提升企業的專業形象與簡約舒適的瀏覽體驗,讓瀏覽者第一眼就愛上她。

實戰| 配置DataDog監控Apache Hudi應用指標_貨運

※評比南投搬家公司費用收費行情懶人包大公開

搬家價格與搬家費用透明合理,不亂收費。本公司提供下列三種搬家計費方案,由資深專業組長到府估價,替客戶量身規劃選擇最經濟節省的計費方式

1. 可用性

在Hudi最新master分支,由Hudi活躍貢獻者Raymond Xu貢獻了DataDog監控Hudi應用指標,該功能將在0.6.0 版本發布,也感謝Raymond的投稿。

2. 簡介

Datadog是一個流行的監控服務。在即將發布的Apache Hudi 0.6.0版本中,除已有的報告者類型(Graphite和JMX)之外,我們將引入通過Datadog HTTP API報告Hudi指標的功能。

3. 配置

類似於其他支持的報告者,啟用Datadog報告者需要以下兩個屬性。

hoodie.metrics.on=true
hoodie.metrics.reporter.type=DATADOG

下面的屬性用來配置Datdog API站點。它會決定請求被發送給api.datadoghq.eu (EU) 還是 api.datadoghq.com (US)。根據你的Datadog賬號作相應配置。

hoodie.metrics.datadog.api.site=EU # 或者 US

hoodie.metrics.datadog.api.key可以讓你配置API密匙。

hoodie.metrics.datadog.api.key=<你的API密匙>
hoodie.metrics.datadog.api.key.supplier=<你的API密匙提供者>

出於安全性考慮,你可能會選擇在運行時返回API密匙。要使用這個方法,需要實現java.util.function.Supplier<String>。並把實現類的完整類名設置到hoodie.metrics.datadog.api.key.supplier。由於hoodie.metrics.datadog.api.key有更高的優先級,也要確保它沒有設置。

下面的屬性用來配置指標前綴,從而區分不同job的指標。

※智慧手機時代的來臨,RWD網頁設計為架站首選

網動結合了許多網際網路業界的菁英共同研發簡單易操作的架站工具,及時性的更新,為客戶創造出更多的網路商機。

hoodie.metrics.datadog.metric.prefix=<你的指標前綴>

注意這裏.會被用來隔離前綴和指標名。比如,如果前綴是foo,則foo.會被加在指標名稱前。

其他的可選屬性在配置參考頁里有相關解釋。

4. 示例演示

在這個示例中,我們運行了一個HoodieDeltaStreamer,啟用了指標收集並做了相應的配置。

如圖所示,我們能收集到Hudi操作相關的指標,比如

  • <前綴>.<表名>.commit.totalScanTime
  • <前綴>.<表名>.clean.duration
  • <前綴>.<表名>.index.lookup.duration

以及HoodieDeltaStreamer相關的指標。

  • <前綴>.<表名>.deltastreamer.duration
  • <前綴>.<表名>.deltastreamer.hiveSyncDuration

. 總結

Hudi提供了多種報告者,方便監控Hudi應用運行時的各項指標,及時發現系統中的問題。

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

※回頭車貨運收費標準

宇安交通關係企業,自成立迄今,即秉持著「以誠待人」、「以實處事」的企業信念

基於 abp vNext 和 .NET Core 開發博客項目 – 博客接口實戰篇(二)_網頁設計公司

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

透過選單樣式的調整、圖片的縮放比例、文字的放大及段落的排版對應來給使用者最佳的瀏覽體驗,所以不用擔心有手機版網站兩個後台的問題,而視覺效果也是透過我們前端設計師優秀的空間比例設計,不會因為畫面變大變小而影響到整體視覺的美感。

系列文章

  1. 基於 abp vNext 和 .NET Core 開發博客項目 – 使用 abp cli 搭建項目
  2. 基於 abp vNext 和 .NET Core 開發博客項目 – 給項目瘦身,讓它跑起來
  3. 基於 abp vNext 和 .NET Core 開發博客項目 – 完善與美化,Swagger登場
  4. 基於 abp vNext 和 .NET Core 開發博客項目 – 數據訪問和代碼優先
  5. 基於 abp vNext 和 .NET Core 開發博客項目 – 自定義倉儲之增刪改查
  6. 基於 abp vNext 和 .NET Core 開發博客項目 – 統一規範API,包裝返回模型
  7. 基於 abp vNext 和 .NET Core 開發博客項目 – 再說Swagger,分組、描述、小綠鎖
  8. 基於 abp vNext 和 .NET Core 開發博客項目 – 接入GitHub,用JWT保護你的API
  9. 基於 abp vNext 和 .NET Core 開發博客項目 – 異常處理和日誌記錄
  10. 基於 abp vNext 和 .NET Core 開發博客項目 – 使用Redis緩存數據
  11. 基於 abp vNext 和 .NET Core 開發博客項目 – 集成Hangfire實現定時任務處理
  12. 基於 abp vNext 和 .NET Core 開發博客項目 – 用AutoMapper搞定對象映射
  13. 基於 abp vNext 和 .NET Core 開發博客項目 – 定時任務最佳實戰(一)
  14. 基於 abp vNext 和 .NET Core 開發博客項目 – 定時任務最佳實戰(二)
  15. 基於 abp vNext 和 .NET Core 開發博客項目 – 定時任務最佳實戰(三)
  16. 基於 abp vNext 和 .NET Core 開發博客項目 – 博客接口實戰篇(一)

上篇文章完成了兩個接口:文章列表頁、文章詳情頁,本篇繼續。

分類列表

分析:這裏多了一個統計文章數量的字段,可以直接新建一個模型QueryCategoryDto.cs繼承CategoryDto

//QueryCategoryDto.cs
namespace Meowv.Blog.Application.Contracts.Blog
{
    public class QueryCategoryDto : CategoryDto
    {
        /// <summary>
        /// 總數
        /// </summary>
        public int Count { get; set; }
    }
}

添加查詢分類列表接口和緩存接口。

//IBlogService.Category.cs
using Meowv.Blog.Application.Contracts.Blog;
using Meowv.Blog.ToolKits.Base;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Meowv.Blog.Application.Blog
{
    public partial interface IBlogService
    {
        /// <summary>
        /// 查詢分類列表
        /// </summary>
        /// <returns></returns>
        Task<ServiceResult<IEnumerable<QueryCategoryDto>>> QueryCategoriesAsync();
    }
}
//IBlogCacheService.Category.cs
using Meowv.Blog.Application.Contracts.Blog;
using Meowv.Blog.ToolKits.Base;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Meowv.Blog.Application.Caching.Blog
{
    public partial interface IBlogCacheService
    {
        /// <summary>
        /// 查詢分類列表
        /// </summary>
        /// <param name="factory"></param>
        /// <returns></returns>
        Task<ServiceResult<IEnumerable<QueryCategoryDto>>> QueryCategoriesAsync(Func<Task<ServiceResult<IEnumerable<QueryCategoryDto>>>> factory);
    }
}

分別實現這兩個接口。

//BlogCacheService.Category.cs
using Meowv.Blog.Application.Contracts.Blog;
using Meowv.Blog.ToolKits.Base;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using static Meowv.Blog.Domain.Shared.MeowvBlogConsts;

namespace Meowv.Blog.Application.Caching.Blog.Impl
{
    public partial class BlogCacheService
    {
        private const string KEY_QueryCategories = "Blog:Category:QueryCategories";

        /// <summary>
        /// 查詢分類列表
        /// </summary>
        /// <param name="factory"></param>
        /// <returns></returns>
        public async Task<ServiceResult<IEnumerable<QueryCategoryDto>>> QueryCategoriesAsync(Func<Task<ServiceResult<IEnumerable<QueryCategoryDto>>>> factory)
        {
            return await Cache.GetOrAddAsync(KEY_QueryCategories, factory, CacheStrategy.ONE_DAY);
        }
    }
}
//BlogService.Category.cs
using Meowv.Blog.Application.Contracts.Blog;
using Meowv.Blog.ToolKits.Base;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Meowv.Blog.Application.Blog.Impl
{
    public partial class BlogService
    {
        /// <summary>
        /// 查詢分類列表
        /// </summary>
        /// <returns></returns>
        public async Task<ServiceResult<IEnumerable<QueryCategoryDto>>> QueryCategoriesAsync()
        {
            return await _blogCacheService.QueryCategoriesAsync(async () =>
            {
                var result = new ServiceResult<IEnumerable<QueryCategoryDto>>();

                var list = from category in await _categoryRepository.GetListAsync()
                           join posts in await _postRepository.GetListAsync()
                           on category.Id equals posts.CategoryId
                           group category by new
                           {
                               category.CategoryName,
                               category.DisplayName
                           } into g
                           select new QueryCategoryDto
                           {
                               CategoryName = g.Key.CategoryName,
                               DisplayName = g.Key.DisplayName,
                               Count = g.Count()
                           };

                result.IsSuccess(list);
                return result;
            });
        }
    }
}

緩存就不說了,查詢分類列表,聯合查詢文章和分類兩張表,關聯字段為CategoryId,然後分組,計算出對應的數量,在BlogController中添加API。

/// <summary>
/// 查詢分類列表
/// </summary>
/// <returns></returns>
[HttpGet]
[Route("categories")]
public async Task<ServiceResult<IEnumerable<QueryCategoryDto>>> QueryCategoriesAsync()
{
    return await _blogService.QueryCategoriesAsync();
}

標籤列表

分析:和分類列表差不多,新建模型QueryTagDto.cs繼承TagDto

//QueryTagDto.cs
namespace Meowv.Blog.Application.Contracts.Blog
{
    public class QueryTagDto : TagDto
    {
        /// <summary>
        /// 總數
        /// </summary>
        public int Count { get; set; }
    }
}

添加查詢標籤列表接口和緩存接口。

//IBlogCacheService.Tag.cs
using Meowv.Blog.Application.Contracts.Blog;
using Meowv.Blog.ToolKits.Base;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Meowv.Blog.Application.Caching.Blog
{
    public partial interface IBlogCacheService
    {
        /// <summary>
        /// 查詢標籤列表
        /// </summary>
        /// <param name="factory"></param>
        /// <returns></returns>
        Task<ServiceResult<IEnumerable<QueryTagDto>>> QueryTagsAsync(Func<Task<ServiceResult<IEnumerable<QueryTagDto>>>> factory);
    }
}
//IBlogService.Tag.cs
using Meowv.Blog.Application.Contracts.Blog;
using Meowv.Blog.ToolKits.Base;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Meowv.Blog.Application.Blog
{
    public partial interface IBlogService
    {
        /// <summary>
        /// 查詢標籤列表
        /// </summary>
        /// <returns></returns>
        Task<ServiceResult<IEnumerable<QueryTagDto>>> QueryTagsAsync();
    }
}

分別實現這兩個接口。

//BlogCacheService.Tag.cs
using Meowv.Blog.Application.Contracts.Blog;
using Meowv.Blog.ToolKits.Base;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using static Meowv.Blog.Domain.Shared.MeowvBlogConsts;

namespace Meowv.Blog.Application.Caching.Blog.Impl
{
    public partial class BlogCacheService
    {
        private const string KEY_QueryTags = "Blog:Tag:QueryTags";

        /// <summary>
        /// 查詢標籤列表
        /// </summary>
        /// <param name="factory"></param>
        /// <returns></returns>
        public async Task<ServiceResult<IEnumerable<QueryTagDto>>> QueryTagsAsync(Func<Task<ServiceResult<IEnumerable<QueryTagDto>>>> factory)
        {
            return await Cache.GetOrAddAsync(KEY_QueryTags, factory, CacheStrategy.ONE_DAY);
        }
    }
}
//BlogService.Tag.cs
using Meowv.Blog.Application.Contracts.Blog;
using Meowv.Blog.ToolKits.Base;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Meowv.Blog.Application.Blog.Impl
{
    public partial class BlogService
    {
        /// <summary>
        /// 查詢標籤列表
        /// </summary>
        /// <returns></returns>
        public async Task<ServiceResult<IEnumerable<QueryTagDto>>> QueryTagsAsync()
        {
            return await _blogCacheService.QueryTagsAsync(async () =>
            {
                var result = new ServiceResult<IEnumerable<QueryTagDto>>();

                var list = from tags in await _tagRepository.GetListAsync()
                           join post_tags in await _postTagRepository.GetListAsync()
                           on tags.Id equals post_tags.TagId
                           group tags by new
                           {
                               tags.TagName,
                               tags.DisplayName
                           } into g
                           select new QueryTagDto
                           {
                               TagName = g.Key.TagName,
                               DisplayName = g.Key.DisplayName,
                               Count = g.Count()
                           };

                result.IsSuccess(list);
                return result;
            });
        }
    }
}

查詢標籤列表需要聯合查詢tags和post_tags,根據TagId進行關聯,然後分組從而獲取標籤下文章的總數,在BlogController中添加API。

/// <summary>
/// 查詢標籤列表
/// </summary>
/// <returns></returns>
[HttpGet]
[Route("tags")]
public async Task<ServiceResult<IEnumerable<QueryTagDto>>> QueryTagsAsync()
{
    return await _blogService.QueryTagsAsync();
}

分類名稱&文章列表

分析:此頁面下包含兩個接口,查詢分類的名稱和當前分類下的文章列表,和文章列表不同的是,它不帶分頁。分類包含兩個字段,分類名稱和展示名稱,我們要把真正的名稱查詢出來展示在頁面上。

分類名稱

不需要給他添加返回模型,直接返回一個string類型即可,同時給一個查詢參數name,添加獲取分類名稱接口和緩存接口。

//IBlogService.Category.cs
/// <summary>
/// 獲取分類名稱
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
Task<ServiceResult<string>> GetCategoryAsync(string name);
//IBlogCacheService.Category.cs
/// <summary>
/// 獲取分類名稱
/// </summary>
/// <param name="name"></param>
/// <param name="factory"></param>
/// <returns></returns>
Task<ServiceResult<string>> GetCategoryAsync(string name, Func<Task<ServiceResult<string>>> factory);

實現這兩個接口。

//BlogCacheService.Category.cs
...
    public partial class BlogCacheService
    {
        private const string KEY_GetCategory = "Blog:Category:GetCategory-{0}";

        /// <summary>
        /// 獲取分類名稱
        /// </summary>
        /// <param name="name"></param>
        /// <param name="factory"></param>
        /// <returns></returns>
        public async Task<ServiceResult<string>> GetCategoryAsync(string name, Func<Task<ServiceResult<string>>> factory)
        {
            return await Cache.GetOrAddAsync(KEY_GetCategory.FormatWith(name), factory, CacheStrategy.ONE_DAY);
        }
    }
...
//BlogService.Category.cs
/// <summary>
/// 獲取分類名稱
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public async Task<ServiceResult<string>> GetCategoryAsync(string name)
{
    return await _blogCacheService.GetCategoryAsync(name, async () =>
    {
        var result = new ServiceResult<string>();

        var category = await _categoryRepository.FindAsync(x => x.DisplayName.Equals(name));
        if (null == category)
        {
            result.IsFailed(ResponseText.WHAT_NOT_EXIST.FormatWith("分類", name));
            return result;
        }

        result.IsSuccess(category.CategoryName);
        return result;
    });
}

FormatWith()是擴展方法,ResponseText.WHAT_NOT_EXIST是之前說過的常量,直接查詢是否存在當前name的分類,如果不存在給出錯誤提示,存在的話,則只返回分類名稱,在BlogController中添加API。

/// <summary>
/// 獲取分類名稱
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
[HttpGet]
[Route("category")]
public async Task<ServiceResult<string>> GetCategoryAsync(([Required] string name)
{
    return await _blogService.GetCategoryAsync(name);
}

[Required]Attribute 指定參數name必填。

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

節能減碳愛地球是景泰電動車的理念,是創立景泰電動車行的初衷,滿意態度更是服務客戶的最高品質,我們的成長來自於你的推薦。

文章列表

通過分類名稱查詢文章列表和分頁查詢文章列表返回模型是一樣的,只是不用分頁,所以直接返回一個列表就可以了,添加通過分類名稱查詢文章列表和緩存的接口。

//IBlogService.Post.cs
/// <summary>
/// 通過分類名稱查詢文章列表
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
Task<ServiceResult<IEnumerable<QueryPostDto>>> QueryPostsByCategoryAsync(string name);
//IBlogCacheService.Post.cs
/// <summary>
/// 通過分類名稱查詢文章列表
/// </summary>
/// <param name="name"></param>
/// <param name="factory"></param>
/// <returns></returns>
Task<ServiceResult<IEnumerable<QueryPostDto>>> QueryPostsByCategoryAsync(string name, Func<Task<ServiceResult<IEnumerable<QueryPostDto>>>> factory);

分別實現這兩個接口。

//BlogCacheService.Post.cs
...
    public partial class BlogCacheService
    {
        private const string KEY_QueryPostsByCategory = "Blog:Post:QueryPostsByCategory-{0}";

        /// <summary>
        /// 通過分類名稱查詢文章列表
        /// </summary>
        /// <param name="name"></param>
        /// <param name="factory"></param>
        /// <returns></returns>
        public async Task<ServiceResult<IEnumerable<QueryPostDto>>> QueryPostsByCategoryAsync(string name, Func<Task<ServiceResult<IEnumerable<QueryPostDto>>>> factory)
        {
            return await Cache.GetOrAddAsync(KEY_QueryPostsByCategory.FormatWith(name), factory, CacheStrategy.ONE_DAY);
        }
    }
...
//BlogService.Post.cs
/// <summary>
/// 通過分類名稱查詢文章列表
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public async Task<ServiceResult<IEnumerable<QueryPostDto>>> QueryPostsByCategoryAsync(string name)
{
    return await _blogCacheService.QueryPostsByCategoryAsync(name, async () =>
    {
        var result = new ServiceResult<IEnumerable<QueryPostDto>>();

        var list = (from posts in await _postRepository.GetListAsync()
                    join categories in await _categoryRepository.GetListAsync()
                    on posts.CategoryId equals categories.Id
                    where categories.DisplayName.Equals(name)
                    orderby posts.CreationTime descending
                    select new PostBriefDto
                    {
                        Title = posts.Title,
                        Url = posts.Url,
                        Year = posts.CreationTime.Year,
                        CreationTime = posts.CreationTime.TryToDateTime()
                    })
                   .GroupBy(x => x.Year)
                   .Select(x => new QueryPostDto
                   {
                       Year = x.Key,
                       Posts = x.ToList()
                   });

        result.IsSuccess(list);
        return result;
    });
}

這個邏輯和分頁查詢文章列表是差不多的,聯合查詢文章表和分類表,關聯字段為CategoryId,指定查詢條件categories.DisplayName==name,以CreationTime倒序排序,年份分組,篩選出所需字段返回,在BlogController中添加API。

/// <summary>
/// 通過分類名稱查詢文章列表
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
[HttpGet]
[Route("posts/category")]
public async Task<ServiceResult<IEnumerable<QueryPostDto>>> QueryPostsByCategoryAsync([Required] string name)
{
    return await _blogService.QueryPostsByCategoryAsync(name);
}

標籤名稱&文章列表

分析:此頁面和分類頁一樣,包含兩個接口,查詢標籤的名稱和當前標籤下的文章列表。

標籤名稱

添加獲取標籤名稱接口和緩存接口,GetTagAsync()

//IBlogService.Tag.cs
/// <summary>
/// 獲取標籤名稱
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
Task<ServiceResult<string>> GetTagAsync(string name);
//IBlogCacheService.Tag.cs
/// <summary>
/// 獲取標籤名稱
/// </summary>
/// <param name="name"></param>
/// <param name="factory"></param>
/// <returns></returns>
Task<ServiceResult<string>> GetTagAsync(string name, Func<Task<ServiceResult<string>>> factory);

實現這兩個接口。

//BlogCacheService.Tag.cs
...
    public partial class BlogCacheService
    {
        private const string KEY_GetTag = "Blog:Tag:GetTag-{0}";

        /// <summary>
        /// 獲取標籤名稱
        /// </summary>
        /// <param name="name"></param>
        /// <param name="factory"></param>
        /// <returns></returns>
        public async Task<ServiceResult<string>> GetTagAsync(string name, Func<Task<ServiceResult<string>>> factory)
        {
            return await Cache.GetOrAddAsync(KEY_GetTag.FormatWith(name), factory, CacheStrategy.ONE_DAY);
        }
    }
...
//BlogService.Tag.cs
/// <summary>
/// 獲取標籤名稱
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public async Task<ServiceResult<string>> GetTagAsync(string name)
{
    return await _blogCacheService.GetTagAsync(name, async () =>
    {
        var result = new ServiceResult<string>();

        var tag = await _tagRepository.FindAsync(x => x.DisplayName.Equals(name));
        if (null == tag)
        {
            result.IsFailed(ResponseText.WHAT_NOT_EXIST.FormatWith("標籤", name));
            return result;
        }

        result.IsSuccess(tag.TagName);
        return result;
    });
}

FormatWith()是擴展方法,ResponseText.WHAT_NOT_EXIST是之前說過的常量,直接查詢是否存在當前name的分類,如果不存在給出錯誤提示,存在的話,則只返回分類名稱,在BlogController中添加API。

/// <summary>
/// 獲取標籤名稱
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
[HttpGet]
[Route("tag")]
public async Task<ServiceResult<string>> GetTagAsync(string name)
{
    return await _blogService.GetTagAsync(name);
}

[Required]Attribute 指定參數name必填。

文章列表

和上面一模一樣的,添加通過標籤名稱查詢文章列表接口和緩存接口。

//IBlogService.Post.cs
/// <summary>
/// 通過標籤名稱查詢文章列表
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
Task<ServiceResult<IEnumerable<QueryPostDto>>> QueryPostsByTagAsync(string name);
//IBlogCacheService.Post.cs
/// <summary>
/// 通過標籤名稱查詢文章列表
/// </summary>
/// <param name="name"></param>
/// <param name="factory"></param>
/// <returns></returns>
Task<ServiceResult<IEnumerable<QueryPostDto>>> QueryPostsByTagAsync(string name, Func<Task<ServiceResult<IEnumerable<QueryPostDto>>>> factory);

分別實現這兩個接口。

//BlogCacheService.Post.cs
...
    public partial class BlogCacheService
    {
        private const string KEY_QueryPostsByTag = "Blog:Post:QueryPostsByTag-{0}";

        /// <summary>
        /// 通過標籤名稱查詢文章列表
        /// </summary>
        /// <param name="name"></param>
        /// <param name="factory"></param>
        /// <returns></returns>
        public async Task<ServiceResult<IEnumerable<QueryPostDto>>> QueryPostsByTagAsync(string name, Func<Task<ServiceResult<IEnumerable<QueryPostDto>>>> factory)
        {
            return await Cache.GetOrAddAsync(KEY_QueryPostsByTag.FormatWith(name), factory, CacheStrategy.ONE_DAY);
        }
    }
...
//BlogService.Post.cs
/// <summary>
/// 通過標籤名稱查詢文章列表
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public async Task<ServiceResult<IEnumerable<QueryPostDto>>> QueryPostsByTagAsync(string name)
{
    return await _blogCacheService.QueryPostsByTagAsync(name, async () =>
    {
        var result = new ServiceResult<IEnumerable<QueryPostDto>>();

        var list = (from post_tags in await _postTagRepository.GetListAsync()
                    join tags in await _tagRepository.GetListAsync()
                    on post_tags.TagId equals tags.Id
                    join posts in await _postRepository.GetListAsync()
                    on post_tags.PostId equals posts.Id
                    where tags.DisplayName.Equals(name)
                    orderby posts.CreationTime descending
                    select new PostBriefDto
                    {
                        Title = posts.Title,
                        Url = posts.Url,
                        Year = posts.CreationTime.Year,
                        CreationTime = posts.CreationTime.TryToDateTime()
                    })
                    .GroupBy(x => x.Year)
                    .Select(x => new QueryPostDto
                    {
                        Year = x.Key,
                        Posts = x.ToList()
                    });

        result.IsSuccess(list);
        return result;
    });
}

這個查詢有點特殊,聯合查詢了3張表,先查post_tags和tags,關聯字段TagId,再根據PostId查詢posts,指定查詢條件tags.DisplayName==name,以CreationTime倒序排序,年份分組,篩選出所需字段返回,在BlogController中添加API。

/// <summary>
/// 通過標籤名稱查詢文章列表
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
[HttpGet]
[Route("posts/tag")]
public async Task<ServiceResult<IEnumerable<QueryPostDto>>> QueryPostsByTagAsync(string name)
{
    return await _blogService.QueryPostsByTagAsync(name);
}

至此,基本上完成了博客前端所需的所有查詢接口,就還剩下友鏈的查詢,大家可以自己完成,後面如果需要什麼新的接口再回頭來寫就好了。

開源地址:https://github.com/Meowv/Blog/tree/blog_tutorial

搭配下方課程學習更佳 ↓ ↓ ↓

http://gk.link/a/10iQ7

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

南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

搬家費用:依消費者運送距離、搬運樓層、有無電梯、步行距離、特殊地形、超重物品等計價因素後,評估每車次單

Asp.net MVC Razor視圖模版動態渲染PDF,Razor模版生成靜態Html_包裝設計

南投搬家公司費用需注意的眉眉角角,別等搬了再說!

上新台中搬家公司提供您一套專業有效率且人性化的辦公室搬遷、公司行號搬家及工廠遷廠的搬家服務

1.前言

 

    上一篇文章我開源了輪子,Asp.net Core 3.1 Razor視圖模版動態渲染PDF,然後,很多小夥伴有很多私信找我了。那麼我下面就簡單的給大家說一下,關於小夥伴問的這些問題。

  • 我項目的电子簽章部分代碼可否開源?

  答:我項目电子簽章也是使用第三方的电子簽章,电子簽章並不是自己實現的,項目裏面的电子簽章代碼無非也是對接第三方的接口。這部分代碼開源出去也沒有什麼意義。我們是使用数字廣東的方案,如果您也是使用該数字簽章,可以私下溝通我看看能不能幫助您。

  • 电子簽章實現難不難,怎麼實現自己的电子簽章?

  答:电子簽章要實現,估計不是太難,按照我的理解,當然我沒有具體深入研究(如果這裏我有妄自菲薄的意思,請諒解,畢竟我能力有限,只是按照我的理解來分析),我個人覺得电子簽章應該就是利用数字證書給PDF簽名,然後加密保護文檔,然後校驗文檔的真偽,就要考慮怎麼驗證這個文檔沒有被刪改,是當初我們簽章的這個文檔,而且這個簽名不能被偽造。個人覺得不是很複雜,但是,电子簽章的法律有效性卻不是這麼簡單的。按照國家法律規定,利用的簽名平台應該有資質的,國家認可的第三方簽章平台,也就是說,私人自己製作的簽章,打起官司來,很難得到法律支持。

  • 項目為什麼CSS樣式不起效?

  答:你是否使用了外鏈的CSS樣式,因為渲染Razor視圖是在後台渲染,無法找到外鏈的文件路徑,就使用不了外鏈的CSS樣式,內嵌和內聯CSS樣式都沒啥問題的。

  • 用word或者excel模版他不香嗎?為什麼要搞個這個東西?

  答:無非是多一個方案,具體你使用什麼完全是你自己說了算,你覺得其他方案好就用,你覺得本方案能幫助你就用,不好就不用,我又不收你半毛線,還是想說的是,你其他的方案,能有用CSS那麼容易做出來漂亮的表單效果嗎?

  • 圖片支持嗎?

  答:圖片要轉Base64編碼,不支持外連接圖片。

  • 前端預覽PDF用什麼插件?

  答:我目前不用插件,新一代瀏覽器都支持PDF直接預覽,直接就能渲染成PDF呈現,當然你也可以自己集成PDF.JS.我大概看了下,集成也很方便。我之所以不集成,是考慮到我的項目有可能使用IE低版本的情況,PDF.JS可能不支持。所以乾脆直接把PDF流推送給瀏覽器,瀏覽器要是能預覽,就直接呈現,不能預覽就下載。

  • 項目支持net Framework嗎?為啥報錯?

  答:這個問題問的有點多,所以本文後續就以這個再說一下本輪子在net45下的使用。還是那句話,有不對的,歡迎您指正,覺得對你有用的就用,無用的就直接忽視,我又不收你半毛線。

  • 可以用本項目生成靜態Html嗎?容易被搜索引擎抓取。

  答:可以,後面演示

 

  2.依賴項目

  <PackageReference Include=”TuesPechkin” Version=”2.1.1″ />
  <PackageReference Include=”TuesPechkin.Wkhtmltox.Win32″ Version=”0.12.2.1″ />
  <PackageReference Include=”RazorEngine” Version=”3.9.3″ />
  <PackageReference Include=”System.ComponentModel.Annotations” Version=”4.5.0″ />
  <PackageReference Include=”Microsoft.AspNet.Mvc” Version=”5.2.3″ />
  <PackageReference Include=”Nito.AsyncEx” Version=”4.0.1″ />
  <PackageReference Include=”Newtonsoft.Json” Version=”12.0.3″ />
  <Reference Include=”Nito.AsyncEx.Concurrent” Version=”4.0.1″ />
  <Reference Include=”Nito.AsyncEx.Enlightenment” Version=”4.0.1″ />

 

     3.核心代碼

    TuesPechkin插件,首先說一下這個TuesPechkin插件,他其實是利用TuesPechkin.Wkhtmltox進程來轉換的。這個插件使用還是要小心的,使用不當可能有線程安全問題,會使得當前工作進程掛起。在IIS下面使用也要注意使用32位的插件。具體使用請看作者的說明:https://github.com/tuespetre/TuesPechkin/blob/develop/README.md

 

 

 

 插件初始化代碼:

 

  private static readonly IConverter PdfConverter = new ThreadSafeConverter(new RemotingToolset<PdfToolset>(
            new Win32EmbeddedDeployment(
                new TempFolderDeployment())));

  

 切記IIS和多線程一定要靜態單例。使用

 Win32EmbeddedDeployment

ThreadSafeConverter
這兩個類。其他的可能讓你進程掛起的成為可能。
還要用到遠程工具集的PDF工具集。


Razor 轉Html代碼,主要有兩種方式:


第一種使用RazorEngine來轉換:這個主要是傳遞Razor模版進去,轉換。

   protected string RunCompileRazorTemplate(object model,string razorTemplateStr)
        {
            if(string.IsNullOrWhiteSpace(razorTemplateStr)) throw new ArgumentException("Razor模版不能為空"); var htmlString= Engine.Razor.RunCompile(razorTemplateStr, razorTemplateStr.GetHashCode().ToString(), null, model); return htmlString; }

 

第二種使用ViewEngine。這個主要是自動查找Asp.net MVC裏面的View下面的Razor,目前我們項目就是使用這個。

 

var viewName = context.RouteData.Values["action"].ToString();
            var result = ViewEngines.Engines.FindView(context, viewName, null); IExportPdfByHtmlTemplate exportPdfByHtmlTemplate = new PdfByHtmlTemplateExporter (); #endif if (result.View == null) throw new ArgumentException($"名稱為:{viewName}的視圖不存在,請檢查!"); context.HttpContext.Response.ContentType = "application/pdf"; //context.HttpContext.Response.Headers.Add("Content-Disposition", "attachment; filename=test.pdf"); var html = ""; using (var stringWriter = new StringWriter()) { #if !NET45 var viewDictionary = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary()) { Model = Value }; var viewContext = new ViewContext(context, result.View, viewDictionary, new TempDataDictionary(context.HttpContext, tempDataProvider), stringWriter, new HtmlHelperOptions()); await result.View.RenderAsync(viewContext); #else var viewDictionary = new ViewDataDictionary(new ModelStateDictionary()) { Model = Value }; var viewContext = new ViewContext(context, result.View, viewDictionary, context.Controller.TempData, stringWriter); result.View.Render(viewContext, stringWriter); result.ViewEngine.ReleaseView(context, result.View); #endif html = stringWriter.ToString(); }

 

推送PDF流給客戶端,預覽PDF主要代碼

 

          context.HttpContext.Response.ContentType = "application/pdf";
    context.HttpContext.Response.AddHeader("Content-Length", buff.Length.ToString());
            context.HttpContext.Response.AddHeader("Content-Disposition", "filename=电子簽章PDF-"+DateTime.Now.ToString()+".pdf");
            context.HttpContext.Response.BinaryWrite(buff);
            context.HttpContext.Response.Flush();
            context.HttpContext.Response.Close();
            context.HttpContext.Response.End();

  

 這裏要注意三個地方,不然一定會踩坑。

Content-Length要設置,不然谷歌瀏覽器可能無法下載預覽的PDF。
Content-Disposition不能要attachment,否則可能直接下載不是預覽。
ContentType 要設置"application/pdf"


Razor轉靜態Html

還有一部分人問我怎麼利用本插件Razor模版動態生成靜態Html,這樣容易被百度爬蟲錄取。
其實這部分核心代碼就是幾句代碼,非常簡單。本項目直接用下面接口即可生成html字符轉,自行保存就可以了。

 public interface IHtmlByRazorTemplateExporter
    {
        Task<string> ExportHtmlByRazorTemplateAsync<T>(T data, string htmlTemplate) where T : class;
        string ExportHtmlByRazorTemplate<T>(T data, string htmlTemplate) where T : class;
    }

  

核心:

 

   protected string RunCompileRazorTemplate(object model,string razorTemplateStr)
        {
            if(string.IsNullOrWhiteSpace(razorTemplateStr)) throw new ArgumentException("Razor模版不能為空"); var htmlString= Engine.Razor.RunCompile(razorTemplateStr, razorTemplateStr.GetHashCode().ToString(), null, model); return htmlString; }

 

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

網動廣告出品的網頁設計,採用精簡與質感的CSS語法,提升企業的專業形象與簡約舒適的瀏覽體驗,讓瀏覽者第一眼就愛上她。

  4.使用方式

  •  目前本項目已經打包成nuget,並上傳,使用可以直接項目右鍵->管理NuGet程序包,查找,然後下載安裝。

 

  •  也可以使用命令安裝。install-package JESAI.HtmlTemplate.Pdf.net45

 

  • 或者直接fork本倉庫自己打包,並根據自己情況修改使用。

 

自定打包可以修改項目目標框架。項目右鍵->屬性->應用程序,目標框架,修改

 

 

 

如發現不能修改,可以,項目->右鍵->編輯項目文件

 

 

 

然後編譯,就可以使用了。

 

具體使用

方式一:

 

 

 方式二:

 

 

 

 

Razor視圖模版代碼:

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">

<head>
    <meta charset="utf-8" />
    <title></title>
</head>

<body>
    <table border="1" style="width:800px;height:500px;">
        <tr>
            <td>姓名</td>
            <td>@Model.Name</td>
            <td>性別</td>
            <td>@Model.Sex</td>
        </tr>
        <tr>
            <td>年齡</td>
            <td>@Model.Age</td>
            <td>班級</td>
            <td>@Model.Class</td>
        </tr>
        <tr>
            <td>住址</td>
            <td>@Model.Address</td>
            <td>電話</td>
            <td>@Model.Tel</td>
        </tr>
        <tr>
            <td clospan="2">住址</td>
            <td>@Model.Des</td>
        </tr>
    </table>
</body>
</html>

 

 

 

  5.運行效果

 

 

 

  6.項目代碼

 代碼託管:https://gitee.com/Jesai/JESAI.HtmlTemplate.Pdf

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

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

窩窩觸角包含自媒體、自有平台及其他國家營銷業務等,多角化經營並具有國際觀的永續理念。

5℃變21.7℃ 挪威北極圈群島氣溫飆升創歷史新高_貨運

※回頭車貨運收費標準

宇安交通關係企業,自成立迄今,即秉持著「以誠待人」、「以實處事」的企業信念

摘錄自2020年07月26日蘋果日報報導

挪威氣象研究所通報,位於北極圈內的斯瓦巴(Svalbard)群島氣溫25日創下歷史新高,來到攝氏21.7°C,當地每年此時氣溫通常都在攝氏5°C到8°C之間。根據科學研究,北極圈內全球暖化速度是地表其他地方的兩倍。

挪威氣候研究中心(Norwegian Centre for Climate Studies)去年2月表示,斯瓦巴群島從70年代初期開始,平均氣溫已躍升攝氏3到5°C,若全球溫室氣體排放量持續增加,預料到了2100年氣溫恐上升攝氏10°C。

※智慧手機時代的來臨,RWD網頁設計為架站首選

網動結合了許多網際網路業界的菁英共同研發簡單易操作的架站工具,及時性的更新,為客戶創造出更多的網路商機。

以北極熊棲息地聞名的斯瓦巴群島上有一座煤礦場,開挖所有能源中最會助長全球暖化的煤礦,也有為了「世界末日」作準備的種子庫,從2008年開始收集並儲存世界上的農作物,以防全球發生大災難。

氣候變遷
國際新聞
挪威
北極圈
全球暖化

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

※評比南投搬家公司費用收費行情懶人包大公開

搬家價格與搬家費用透明合理,不亂收費。本公司提供下列三種搬家計費方案,由資深專業組長到府估價,替客戶量身規劃選擇最經濟節省的計費方式

歐洲農業政策里程碑 3900億歐元補助 只給氣候友善農民_網頁設計公司

南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

搬家費用:依消費者運送距離、搬運樓層、有無電梯、步行距離、特殊地形、超重物品等計價因素後,評估每車次單

環境資訊中心綜合外電;姜唯 編譯;林大利 審校

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

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

透過選單樣式的調整、圖片的縮放比例、文字的放大及段落的排版對應來給使用者最佳的瀏覽體驗,所以不用擔心有手機版網站兩個後台的問題,而視覺效果也是透過我們前端設計師優秀的空間比例設計,不會因為畫面變大變小而影響到整體視覺的美感。

猛虎咬死三人 印度放棄野放_包裝設計

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

網動廣告出品的網頁設計,採用精簡與質感的CSS語法,提升企業的專業形象與簡約舒適的瀏覽體驗,讓瀏覽者第一眼就愛上她。

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

印度一隻咬死三個人的老虎,餘生都將被關起來,當局今(7日)表示,讓這隻老虎四處漫遊「實在太危險」。

馬德雅省首席野生動物管理員曼達爾(S.K. Mandal)告訴法新社:「我們給了牠幾次機會,希望能野放牠,但牠總是闖入人類居住地。」

過去10年,人口13億的印度一再看到人類與動物間發生致命衝突。根據政府統計,2014年到2019年間有近225人遭老虎攻擊喪命。同時有數據顯示,2012年到2018年間,有超過200隻老虎因人類盜獵或架設電網而喪命。

南投搬家公司費用需注意的眉眉角角,別等搬了再說!

上新台中搬家公司提供您一套專業有效率且人性化的辦公室搬遷、公司行號搬家及工廠遷廠的搬家服務

世界上70%的老虎在印度棲息。政府去年表示,境內老虎數量從2006年1411隻的史上最低紀錄,增加到2018年2967隻。

※ 本文與 行政院農業委員會 林務局   合作刊登

國際新聞
印度
老虎
人與動物衝突事件簿
處變不驚──與野生動物相遇

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

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

窩窩觸角包含自媒體、自有平台及其他國家營銷業務等,多角化經營並具有國際觀的永續理念。

容器技術之Dockerfile(二)_貨運

※智慧手機時代的來臨,RWD網頁設計為架站首選

網動結合了許多網際網路業界的菁英共同研發簡單易操作的架站工具,及時性的更新,為客戶創造出更多的網路商機。

  前文我們聊到了什麼是dockerfile,它的主要作用以及dockerfile的一些基本指令的使用方法,回顧請參考https://www.cnblogs.com/qiuhom-1874/p/13019411.html;今天我們在來聊一聊dockerfile餘下指令的用法和作用;

  1、RUN:該指令用於docker build 過程中運行的程序,可以是任何命令;語法格式RUN <command> 或RUN [“<executable>”, “<param1>”, “<param2>”];第一種格式中,<command>通常是一個shell命令,且以“/bin/sh -c”來運行它,這意味着此進程在容器中的PID不為1,不能接收Unix信號,因此,當使用docker stop <container>命令停止容器時,此進程接收不到SIGTERM信號; 第二種語法格式中的參數是一個JSON格式的數組,其中<executable>為要運行的命令,後面的<paramN>為傳遞給命令的選項或參數;然而,此種格式指定的命令不會以“/bin/sh -c”來發起,因此常見的shell操作如變量替換以及通配符(?,*等)替換將不會進行;不過,如果要運行的命令依賴於此shell特性的話,可以將其替換為 RUN [“/bin/sh”, “-c”, “<executable>”, “<param1>”]這樣的格式;注意:json數組中,要使用雙引號;

  示例:

[root@node1 test]# cat Dockerfile 
FROM centos:7 

MAINTAINER "qiuhom <qiuhom@linux-1874.com>"

LABEL version="1.0"

LABEL description="this is test file \ that label-values can span multiple lines."

ARG web_home

COPY html ${web_home:-"/data/htdoc/"}

VOLUME ${web_home:-"/data/htdoc/"}

EXPOSE 80/tcp 443/tcp

RUN mkdir -p /aaa/bbb/t{1..4}



[root@node1 test]# 

  提示:以上Dockerfile中,用RUN指令運行了mkdir命令,這種運行命令的方式在就可以利用shell的特性,如上大括號展開功能;

  驗證:build 該dockerfile后,運行該鏡像為容器,看看容器內部是否創建了/aaa/bbb/t1 t2 t3 t4?

[root@node1 test]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
busybox             latest              1c35c4412082        16 hours ago        1.22MB
centos              7                   b5b4d78bc90c        4 weeks ago         203MB
[root@node1 test]# docker build . -t myimg:v1
Sending build context to Docker daemon   1.05MB
Step 1/9 : FROM centos:7
 ---> b5b4d78bc90c
Step 2/9 : MAINTAINER "qiuhom <qiuhom@linux-1874.com>"
 ---> Running in 64c792ce6750
Removing intermediate container 64c792ce6750
 ---> 604899ef29f9
Step 3/9 : LABEL version="1.0"
 ---> Running in 6a3f9b4a9058
Removing intermediate container 6a3f9b4a9058
 ---> d9edea71fa22
Step 4/9 : LABEL description="this is test file \ that label-values can span multiple lines."
 ---> Running in b191ab5e19f9
Removing intermediate container b191ab5e19f9
 ---> ee027bbdc04b
Step 5/9 : ARG web_home
 ---> Running in a4c86febf616
Removing intermediate container a4c86febf616
 ---> 5b25bb7421dd
Step 6/9 : COPY html ${web_home:-"/data/htdoc/"}
 ---> 7c7a667149fa
Step 7/9 : VOLUME ${web_home:-"/data/htdoc/"}
 ---> Running in f9ec02d8f736
Removing intermediate container f9ec02d8f736
 ---> 86c7226f6b21
Step 8/9 : EXPOSE 80/tcp 443/tcp
 ---> Running in ad82d389ac25
Removing intermediate container ad82d389ac25
 ---> 28dadea40aff
Step 9/9 : RUN mkdir -p /aaa/bbb/t{1..4}
 ---> Running in 1013a212d3f2
Removing intermediate container 1013a212d3f2
 ---> 7f109a34a4a5
Successfully built 7f109a34a4a5
Successfully tagged myimg:v1
[root@node1 test]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
myimg               v1                  7f109a34a4a5        4 seconds ago       203MB
busybox             latest              1c35c4412082        16 hours ago        1.22MB
centos              7                   b5b4d78bc90c        4 weeks ago         203MB
[root@node1 test]# docker run --name test --rm -it myimg:v1 /bin/bash
[root@fc89ca934ed5 /]# ls /
aaa                bin   dev  home  lib64  mnt  proc  run   srv  tmp  var
anaconda-post.log  data  etc  lib   media  opt  root  sbin  sys  usr
[root@fc89ca934ed5 /]# ls /aaa/
bbb
[root@fc89ca934ed5 /]# ls /aaa/bbb/
t1  t2  t3  t4
[root@fc89ca934ed5 /]# exit
exit
[root@node1 test]# 

  提示:底層基礎鏡像的shell如果不支持大括號展開,那麼我們基於這種鏡像做出來的鏡像運行以上命令也就不支持shell的大括號展開功能;

  示例:

[root@node1 test]# cat Dockerfile
FROM centos:7

MAINTAINER "qiuhom <qiuhom@linux-1874.com>"

LABEL version="1.0"

LABEL description="this is test file \ that label-values can span multiple lines."

ARG web_home

COPY html ${web_home:-"/data/htdoc/"}

VOLUME ${web_home:-"/data/htdoc/"}

EXPOSE 80/tcp 443/tcp

RUN mkdir -p /aaa/bbb/t{1..4}

RUN ["mkdir","-p","/ccc/ddd/f{1..4}"]

[root@node1 test]# 

  提示:以json數組格式的方式去運行命令,它默認是不支持shell的任何特性,這意味着運行該命令時,不是基於shell子進程的方式在執行命令,通常是內核直接執行了;所以上面的命令它會把大括號處理成字符,而不會展開;

  驗證:build成鏡像運行成容器,看看是否把大括號處理成字符了?

[root@node1 test]# docker build . -t myimg:v1.1
Sending build context to Docker daemon   1.05MB
Step 1/10 : FROM centos:7
 ---> b5b4d78bc90c
Step 2/10 : MAINTAINER "qiuhom <qiuhom@linux-1874.com>"
 ---> Using cache
 ---> 604899ef29f9
Step 3/10 : LABEL version="1.0"
 ---> Using cache
 ---> d9edea71fa22
Step 4/10 : LABEL description="this is test file \ that label-values can span multiple lines."
 ---> Using cache
 ---> ee027bbdc04b
Step 5/10 : ARG web_home
 ---> Using cache
 ---> 5b25bb7421dd
Step 6/10 : COPY html ${web_home:-"/data/htdoc/"}
 ---> Using cache
 ---> 7c7a667149fa
Step 7/10 : VOLUME ${web_home:-"/data/htdoc/"}
 ---> Using cache
 ---> 86c7226f6b21
Step 8/10 : EXPOSE 80/tcp 443/tcp
 ---> Using cache
 ---> 28dadea40aff
Step 9/10 : RUN mkdir -p /aaa/bbb/t{1..4}
 ---> Using cache
 ---> 7f109a34a4a5
Step 10/10 : RUN ["mkdir","-p","/ccc/ddd/f{1..4}"]
 ---> Running in 9da1e6bab59f
Removing intermediate container 9da1e6bab59f
 ---> ae463ec8cbd9
Successfully built ae463ec8cbd9
Successfully tagged myimg:v1.1
[root@node1 test]# docker run --name test --rm -it myimg:v1.1 /bin/bash
[root@02ec6e404100 /]# ls /
aaa                bin  data  etc   lib    media  opt   root  sbin  sys  usr
anaconda-post.log  ccc  dev   home  lib64  mnt    proc  run   srv   tmp  var
[root@02ec6e404100 /]# ls /ccc/ddd/
f{1..4}
[root@02ec6e404100 /]# 

  提示:可以看到在/ccc/ddd/目錄下並沒有把大括號展開,而是直接把它當成了字符處理了;如果我們想要用json數組這種方式運行命令,又想讓使用shell特性,我們可以使用”/bin/sh -c”來明確聲明後面的命令用shell子進程的方式運行;如下所示

[root@node1 test]# cat Dockerfile
FROM centos:7

MAINTAINER "qiuhom <qiuhom@linux-1874.com>"

LABEL version="1.0"

LABEL description="this is test file \ that label-values can span multiple lines."

ARG web_home

COPY html ${web_home:-"/data/htdoc/"}

VOLUME ${web_home:-"/data/htdoc/"}

EXPOSE 80/tcp 443/tcp

RUN mkdir -p /aaa/bbb/t{1..4}

RUN ["/bin/bash","-c","mkdir -p /ccc/ddd/f{1..4}"]

[root@node1 test]# 

  提示:以上運行命令的方式就明確聲明使用shell子進程的方式運行命令;這裏需要注意一點的是,如果使用json數組的方式運行命令,後面真正執行的命令要一個整體當作參數傳給”/bin/bash”

  驗證:看看是否會把大括號展開?

[root@node1 test]# docker build . -t myimg:v1.2
Sending build context to Docker daemon   1.05MB
Step 1/10 : FROM centos:7
 ---> b5b4d78bc90c
Step 2/10 : MAINTAINER "qiuhom <qiuhom@linux-1874.com>"
 ---> Using cache
 ---> 604899ef29f9
Step 3/10 : LABEL version="1.0"
 ---> Using cache
 ---> d9edea71fa22
Step 4/10 : LABEL description="this is test file \ that label-values can span multiple lines."
 ---> Using cache
 ---> ee027bbdc04b
Step 5/10 : ARG web_home
 ---> Using cache
 ---> 5b25bb7421dd
Step 6/10 : COPY html ${web_home:-"/data/htdoc/"}
 ---> Using cache
 ---> 7c7a667149fa
Step 7/10 : VOLUME ${web_home:-"/data/htdoc/"}
 ---> Using cache
 ---> 86c7226f6b21
Step 8/10 : EXPOSE 80/tcp 443/tcp
 ---> Using cache
 ---> 28dadea40aff
Step 9/10 : RUN mkdir -p /aaa/bbb/t{1..4}
 ---> Using cache
 ---> 7f109a34a4a5
Step 10/10 : RUN ["/bin/bash","-c","mkdir -p /ccc/ddd/f{1..4}"]
 ---> Running in a5785a139e1f
Removing intermediate container a5785a139e1f
 ---> 30a5f5594104
Successfully built 30a5f5594104
Successfully tagged myimg:v1.2
[root@node1 test]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
myimg               v1.2                30a5f5594104        5 seconds ago       203MB
myimg               v1.1                ae463ec8cbd9        9 minutes ago       203MB
myimg               v1                  7f109a34a4a5        21 minutes ago      203MB
busybox             latest              1c35c4412082        16 hours ago        1.22MB
centos              7                   b5b4d78bc90c        4 weeks ago         203MB
[root@node1 test]# docker run --name test --rm -it myimg:v1.2 /bin/bash
[root@549f875aa4de /]# ls /
aaa                bin  data  etc   lib    media  opt   root  sbin  sys  usr
anaconda-post.log  ccc  dev   home  lib64  mnt    proc  run   srv   tmp  var
[root@549f875aa4de /]# ls /ccc/ddd/
f1  f2  f3  f4
[root@549f875aa4de /]# 

  提示:可以看到用”/bin/bash -c” 是可以明確聲明後面的命令用shell子進程的方式運行,這樣一來就可以在後面的命令使用shell特性的語法;

  2、CMD:該指令類似於RUN指令,CMD指令也可用於運行任何命令或應用程序,不過,二者的運行時間點不同; RUN指令運行於映像文件構建過程中,而CMD指令運行於基於Dockerfile構建出的新映像文件啟動一個容器時; CMD指令的首要目的在於為啟動的容器指定默認要運行的程序,且其運行結束后,容器也將終止;不過,CMD指定的命令其可以被docker run的命令行選項所覆蓋;在Dockerfile中可以存在多個CMD指令,但僅最後一個會生效;語法格式 CMD <command> 或 CMD [“<executable>”, “<param1>”, “<param2>”] 或 CMD [“<param1>”,”<param2>”];前兩種語法格式的意義同RUN,第三種則用於為ENTRYPOINT指令提供默認參數;

  示例:

[root@node1 test]# cat Dockerfile
FROM busybox:latest

MAINTAINER "qiuhom <qiuhom@linux-1874.com>"

LABEL version="1.0"

LABEL description="this is test file \ that label-values can span multiple lines."

ARG web_home

COPY html ${web_home:-"/data/htdoc/"}

VOLUME ${web_home:-"/data/htdoc/"}

EXPOSE 80/tcp 443/tcp

CMD httpd -f -h /data/htdoc/
[root@node1 test]# 

  提示:docker容器內部運行的程序必須運行為前台;CMD是指定容器運行時要運行的命令;通常該命令或程序是以前台方式運行;如果不是前台運行,我們的容器就會存在一啟動就退出的情況;以上命令就表示前台運行httpd程序 並指定httpd 的工作目錄為${web_home}變量所指定的目錄;

  驗證:build后看看啟動為容器是否提供80訪問服務?

[root@node1 test]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
myimg               v1.2                30a5f5594104        23 minutes ago      203MB
myimg               v1.1                ae463ec8cbd9        32 minutes ago      203MB
myimg               v1                  7f109a34a4a5        44 minutes ago      203MB
busybox             latest              1c35c4412082        16 hours ago        1.22MB
centos              7                   b5b4d78bc90c        4 weeks ago         203MB
[root@node1 test]# docker build . -t myimg:v1.3
Sending build context to Docker daemon   1.05MB
Step 1/9 : FROM busybox:latest
 ---> 1c35c4412082
Step 2/9 : MAINTAINER "qiuhom <qiuhom@linux-1874.com>"
 ---> Running in deb5e54eef87
Removing intermediate container deb5e54eef87
 ---> baf170e0c586
Step 3/9 : LABEL version="1.0"
 ---> Running in 433669185e0d
Removing intermediate container 433669185e0d
 ---> d96fb4ae3d58
Step 4/9 : LABEL description="this is test file \ that label-values can span multiple lines."
 ---> Running in b5da74e27c69
Removing intermediate container b5da74e27c69
 ---> 62372d19daf3
Step 5/9 : ARG web_home
 ---> Running in 3f65a67bb15a
Removing intermediate container 3f65a67bb15a
 ---> 1ce797c7cde0
Step 6/9 : COPY html ${web_home:-"/data/htdoc/"}
 ---> 15848dea21b9
Step 7/9 : VOLUME ${web_home:-"/data/htdoc/"}
 ---> Running in 868f4c10e00f
Removing intermediate container 868f4c10e00f
 ---> f3ec40d1cb5e
Step 8/9 : EXPOSE 80/tcp 443/tcp
 ---> Running in 7f72c2612e92
Removing intermediate container 7f72c2612e92
 ---> 5ccfc6d604cc
Step 9/9 : CMD httpd -f -h /data/htdoc/
 ---> Running in 95a4fd578821
Removing intermediate container 95a4fd578821
 ---> 2e296b4f4500
Successfully built 2e296b4f4500
Successfully tagged myimg:v1.3
[root@node1 test]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
myimg               v1.3                2e296b4f4500        3 seconds ago       1.22MB
myimg               v1.2                30a5f5594104        23 minutes ago      203MB
myimg               v1.1                ae463ec8cbd9        33 minutes ago      203MB
myimg               v1                  7f109a34a4a5        44 minutes ago      203MB
busybox             latest              1c35c4412082        16 hours ago        1.22MB
centos              7                   b5b4d78bc90c        4 weeks ago         203MB
[root@node1 test]# docker run --name b1 -d myimg:v1.3
c3514f782cffd8140aa7c612293029f4d0302e8d697887dfc2696eea44a31700
[root@node1 test]# docker ps 
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
c3514f782cff        myimg:v1.3          "/bin/sh -c 'httpd -…"   4 seconds ago       Up 3 seconds        80/tcp, 443/tcp     b1
[root@node1 test]# curl http://172.17.0.2/test1.html
this is test1 html
[root@node1 test]# 

  提示:可以看到httpd是可以正常提供服務的;從上面的信息我們也可以了解到運行容器后,它默認是把我們寫的命令當作shell子命令的方式在運行;

  示例:以json數組方式運行命令

[root@node1 test]# cat Dockerfile 
FROM busybox:latest

MAINTAINER "qiuhom <qiuhom@linux-1874.com>"

LABEL version="1.0"

LABEL description="this is test file \ that label-values can span multiple lines."

ARG web_home

COPY html ${web_home:-"/data/htdoc/"}

VOLUME ${web_home:-"/data/htdoc/"}

EXPOSE 80/tcp 443/tcp

CMD ["httpd","-f","-h","/data/htdoc/"]

[root@node1 test]# 

  提示:用json數組格式運行命令,需要把後面的每個選項當作參數傳給httpd;

  驗證:運行容器看看容器是否退出,是否能夠正常提供httpd服務?

[root@node1 test]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
myimg               v1.3                2e296b4f4500        24 minutes ago      1.22MB
myimg               v1.2                30a5f5594104        47 minutes ago      203MB
myimg               v1.1                ae463ec8cbd9        57 minutes ago      203MB
myimg               v1                  7f109a34a4a5        About an hour ago   203MB
busybox             latest              1c35c4412082        17 hours ago        1.22MB
centos              7                   b5b4d78bc90c        4 weeks ago         203MB
[root@node1 test]# docker build . -t myimg:v1.4
Sending build context to Docker daemon   1.05MB
Step 1/9 : FROM busybox:latest
 ---> 1c35c4412082
Step 2/9 : MAINTAINER "qiuhom <qiuhom@linux-1874.com>"
 ---> Using cache
 ---> baf170e0c586
Step 3/9 : LABEL version="1.0"
 ---> Using cache
 ---> d96fb4ae3d58
Step 4/9 : LABEL description="this is test file \ that label-values can span multiple lines."
 ---> Using cache
 ---> 62372d19daf3
Step 5/9 : ARG web_home
 ---> Using cache
 ---> 1ce797c7cde0
Step 6/9 : COPY html ${web_home:-"/data/htdoc/"}
 ---> Using cache
 ---> 15848dea21b9
Step 7/9 : VOLUME ${web_home:-"/data/htdoc/"}
 ---> Using cache
 ---> f3ec40d1cb5e
Step 8/9 : EXPOSE 80/tcp 443/tcp
 ---> Using cache
 ---> 5ccfc6d604cc
Step 9/9 : CMD ["httpd","-f","-h","/data/htdoc/"]
 ---> Running in 5bebdabfe2b7
Removing intermediate container 5bebdabfe2b7
 ---> 58e3b4c40ae7
Successfully built 58e3b4c40ae7
Successfully tagged myimg:v1.4
[root@node1 test]# docker run --name b1 -d myimg:v1.4
a32a05033a6dcb735363906bfcd2b84cfb290ca1b60c17d3ac2f81cdeceee705
[root@node1 test]# docker ps 
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
a32a05033a6d        myimg:v1.4          "httpd -f -h /data/h…"   6 seconds ago       Up 5 seconds        80/tcp, 443/tcp     b1
[root@node1 test]# curl http://172.17.0.2/test1.html
this is test1 html
[root@node1 test]# 

  提示:可以看到httpd服務可以正常提供訪問,說明我們用json數組方式運行命令是正確的;總結一點,用CMD或RUN指令運行命令時,如果直接在CMD或RUN指令後面接命令,這種方式通常會被解釋為啟動一個shell子進程運行命令,RUN指令表現形式就是後面的命令可以使用shell特性的語法格式的命令,比如大括號展開等等;而CMD指令表現形式就是啟動為容器后,它默認會把我們指定運行的命令當作參數傳給“/bin/sh”來運行;CMD或RUN指令加中括號的形式就表示使用json數組格式方式運行命令;這種方式運行命令在CMD中表現形式是我們運行的命令的選項都要當作參數傳給該命令;RUN指令表現形式是不能使用shell特性的命令;如果非要使用shell特性的命令格式,我們需要把我們的命令當作參數傳給“/bin/sh”,當然前提是我們的基礎鏡像shell支持shell特性的語法;

※回頭車貨運收費標準

宇安交通關係企業,自成立迄今,即秉持著「以誠待人」、「以實處事」的企業信念

  3、ENTRYPOINT:該指令類似CMD指令的功能,用於為容器指定默認運行程序,從而使得容器像是一個單獨的可執行程序;與CMD不同的是,由ENTRYPOINT啟動的程序不會被docker run命令行指定的參數所覆蓋,而且,這些命令行參數會被當作參數傳遞給ENTRYPOINT指定的程序(不過,docker run命令的–entrypoint選項的參數可覆蓋ENTRYPOINT指令指定的程序);語法格式 ENTRYPOINT <command>或 ENTRYPOINT [“<executable>”, “<param1>”, “<param2>”];docker run命令傳入的命令參數會覆蓋CMD指令的內容並且附加到ENTRYPOINT命令最後做為其參數使用;Dockerfile文件中也可以存在多個ENTRYPOINT指令,但僅有最後一個會生效;

  示例:

[root@node1 test]# cat Dockerfile
FROM busybox:latest

MAINTAINER "qiuhom <qiuhom@linux-1874.com>"

LABEL version="1.0"

LABEL description="this is test file \ that label-values can span multiple lines."

ARG web_home

COPY html ${web_home:-"/data/htdoc/"}

VOLUME ${web_home:-"/data/htdoc/"}

EXPOSE 80/tcp 443/tcp

ENTRYPOINT httpd -f -h /data/htdoc/
[root@node1 test]# 

  提示:以上dockerfile中用ENTRYPOINT 來指定容器默認運行程序,它和CMD不同的是,CMD指定運行的命令,我們可以使用docker run 命令加要運行的的命令替代容器里默認運行的命令,而ENTRYPOINT指定的命令我們是不可隨便替換的,如果要替換必須要使用–entrypoint選項來指定;

  驗證:build成鏡像,我們啟動為容器直接運行/bin/sh 看看是否可行?

[root@node1 test]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
myimg               v1.4                58e3b4c40ae7        23 minutes ago      1.22MB
myimg               v1.3                2e296b4f4500        47 minutes ago      1.22MB
myimg               v1.2                30a5f5594104        About an hour ago   203MB
myimg               v1.1                ae463ec8cbd9        About an hour ago   203MB
myimg               v1                  7f109a34a4a5        2 hours ago         203MB
busybox             latest              1c35c4412082        17 hours ago        1.22MB
centos              7                   b5b4d78bc90c        4 weeks ago         203MB
[root@node1 test]# docker build . -t myimg:v1.5
Sending build context to Docker daemon   1.05MB
Step 1/9 : FROM busybox:latest
 ---> 1c35c4412082
Step 2/9 : MAINTAINER "qiuhom <qiuhom@linux-1874.com>"
 ---> Using cache
 ---> baf170e0c586
Step 3/9 : LABEL version="1.0"
 ---> Using cache
 ---> d96fb4ae3d58
Step 4/9 : LABEL description="this is test file \ that label-values can span multiple lines."
 ---> Using cache
 ---> 62372d19daf3
Step 5/9 : ARG web_home
 ---> Using cache
 ---> 1ce797c7cde0
Step 6/9 : COPY html ${web_home:-"/data/htdoc/"}
 ---> Using cache
 ---> 15848dea21b9
Step 7/9 : VOLUME ${web_home:-"/data/htdoc/"}
 ---> Using cache
 ---> f3ec40d1cb5e
Step 8/9 : EXPOSE 80/tcp 443/tcp
 ---> Using cache
 ---> 5ccfc6d604cc
Step 9/9 : ENTRYPOINT httpd -f -h /data/htdoc/
 ---> Running in de274d68686c
Removing intermediate container de274d68686c
 ---> 5825c2ec655f
Successfully built 5825c2ec655f
Successfully tagged myimg:v1.5
[root@node1 test]# docker run --name b1 --rm -it myimg:v1.5 /bin/sh

  提示:運行以上命令后,不會給我們一個shell終端,也不報錯;但是我們直接訪問httpd服務是可以正常訪問的;這意味我們用docker run 命令是不能替換我們用entrypoint指定指定的命令的;

  測試:用–entrypoint 選項來看看是否能夠覆蓋ENTRYPOINT指定所指定的命令程序?

[root@node1 test]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
myimg               v1.5                5825c2ec655f        12 minutes ago      1.22MB
myimg               v1.4                58e3b4c40ae7        35 minutes ago      1.22MB
myimg               v1.3                2e296b4f4500        About an hour ago   1.22MB
myimg               v1.2                30a5f5594104        About an hour ago   203MB
myimg               v1.1                ae463ec8cbd9        2 hours ago         203MB
myimg               v1                  7f109a34a4a5        2 hours ago         203MB
busybox             latest              1c35c4412082        17 hours ago        1.22MB
centos              7                   b5b4d78bc90c        4 weeks ago         203MB
[root@node1 test]# docker run --name b1 --rm -it --entrypoint "/bin/sh" myimg:v1.5
/ # ls
bin   data  dev   etc   home  proc  root  sys   tmp   usr   var
/ # ps
PID   USER     TIME  COMMAND
    1 root      0:00 /bin/sh
    7 root      0:00 ps
/ # 

  提示:可以看到使用docker run 必須要加–entrypoint 選項才可以覆蓋ENTRYPOINT指令指定的命令;

  示例:使用json數組格式來指定命令

[root@node1 test]# cat Dockerfile 
FROM busybox:latest

MAINTAINER "qiuhom <qiuhom@linux-1874.com>"

LABEL version="1.0"

LABEL description="this is test file \ that label-values can span multiple lines."

ARG web_home

COPY html ${web_home:-"/data/htdoc/"}

VOLUME ${web_home:-"/data/htdoc/"}

EXPOSE 80/tcp 443/tcp

ENTRYPOINT ["httpd","-f","-h","/data/htdoc/"]

[root@node1 test]# 

  提示:使用json數組格式來指定命令時,都需要將後面的選項和參數當作該命令的參數傳進去;

  測試:使用docker run 直接加命令 看看是否能夠覆蓋ENTRYPOINT指令指定的命令?

  提示:可以看到我們直接使用命令是無法覆蓋ENTRYPOINT指令說指定的命令;

  示例:

[root@node1 test]# cat Dockerfile 
FROM centos:7

MAINTAINER "qiuhom <qiuhom@linux-1874.com>"

LABEL version="1.0"

LABEL description="this is test file \ that label-values can span multiple lines."

RUN yum install -y httpd

EXPOSE 80/tcp 

ENTRYPOINT ["/usr/sbin/httpd","-DFOREGROUND"]

[root@node1 test]# 

  測試:用docker run 命令覆蓋ENTRYPOINT指定的默認命令,看看是否可行?

[root@node1 test]# docker build . -t myimg:v1.7
Sending build context to Docker daemon  1.051MB
Step 1/7 : FROM centos:7
 ---> b5b4d78bc90c
Step 2/7 : MAINTAINER "qiuhom <qiuhom@linux-1874.com>"
 ---> Using cache
 ---> 604899ef29f9
Step 3/7 : LABEL version="1.0"
 ---> Using cache
 ---> d9edea71fa22
Step 4/7 : LABEL description="this is test file \ that label-values can span multiple lines."
 ---> Using cache
 ---> ee027bbdc04b
Step 5/7 : RUN yum install -y httpd
 ---> Running in 164240645e39
Loaded plugins: fastestmirror, ovl
Determining fastest mirrors
 * base: mirrors.aliyun.com
 * extras: mirrors.aliyun.com
 * updates: mirrors.aliyun.com
Resolving Dependencies
--> Running transaction check
---> Package httpd.x86_64 0:2.4.6-93.el7.centos will be installed
--> Processing Dependency: httpd-tools = 2.4.6-93.el7.centos for package: httpd-2.4.6-93.el7.centos.x86_64
--> Processing Dependency: system-logos >= 7.92.1-1 for package: httpd-2.4.6-93.el7.centos.x86_64
--> Processing Dependency: /etc/mime.types for package: httpd-2.4.6-93.el7.centos.x86_64
--> Processing Dependency: libaprutil-1.so.0()(64bit) for package: httpd-2.4.6-93.el7.centos.x86_64
--> Processing Dependency: libapr-1.so.0()(64bit) for package: httpd-2.4.6-93.el7.centos.x86_64
--> Running transaction check
---> Package apr.x86_64 0:1.4.8-5.el7 will be installed
---> Package apr-util.x86_64 0:1.5.2-6.el7 will be installed
---> Package centos-logos.noarch 0:70.0.6-3.el7.centos will be installed
---> Package httpd-tools.x86_64 0:2.4.6-93.el7.centos will be installed
---> Package mailcap.noarch 0:2.1.41-2.el7 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

================================================================================
 Package             Arch          Version                    Repository   Size
================================================================================
Installing:
 httpd               x86_64        2.4.6-93.el7.centos        base        2.7 M
Installing for dependencies:
 apr                 x86_64        1.4.8-5.el7                base        103 k
 apr-util            x86_64        1.5.2-6.el7                base         92 k
 centos-logos        noarch        70.0.6-3.el7.centos        base         21 M
 httpd-tools         x86_64        2.4.6-93.el7.centos        base         92 k
 mailcap             noarch        2.1.41-2.el7               base         31 k

Transaction Summary
================================================================================
Install  1 Package (+5 Dependent packages)

Total download size: 24 M
Installed size: 32 M
Downloading packages:
warning: /var/cache/yum/x86_64/7/base/packages/apr-util-1.5.2-6.el7.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID f4a80eb5: NOKEY
Public key for apr-util-1.5.2-6.el7.x86_64.rpm is not installed
--------------------------------------------------------------------------------
Total                                              7.8 MB/s |  24 MB  00:03     
Retrieving key from file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
Importing GPG key 0xF4A80EB5:
 Userid     : "CentOS-7 Key (CentOS 7 Official Signing Key) <security@centos.org>"
 Fingerprint: 6341 ab27 53d7 8a78 a7c2 7bb1 24c6 a8a7 f4a8 0eb5
 Package    : centos-release-7-8.2003.0.el7.centos.x86_64 (@CentOS)
 From       : /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : apr-1.4.8-5.el7.x86_64                                       1/6 
  Installing : apr-util-1.5.2-6.el7.x86_64                                  2/6 
  Installing : httpd-tools-2.4.6-93.el7.centos.x86_64                       3/6 
  Installing : centos-logos-70.0.6-3.el7.centos.noarch                      4/6 
  Installing : mailcap-2.1.41-2.el7.noarch                                  5/6 
  Installing : httpd-2.4.6-93.el7.centos.x86_64                             6/6 
  Verifying  : mailcap-2.1.41-2.el7.noarch                                  1/6 
  Verifying  : apr-util-1.5.2-6.el7.x86_64                                  2/6 
  Verifying  : httpd-2.4.6-93.el7.centos.x86_64                             3/6 
  Verifying  : apr-1.4.8-5.el7.x86_64                                       4/6 
  Verifying  : httpd-tools-2.4.6-93.el7.centos.x86_64                       5/6 
  Verifying  : centos-logos-70.0.6-3.el7.centos.noarch                      6/6 

Installed:
  httpd.x86_64 0:2.4.6-93.el7.centos                                            

Dependency Installed:
  apr.x86_64 0:1.4.8-5.el7                                                      
  apr-util.x86_64 0:1.5.2-6.el7                                                 
  centos-logos.noarch 0:70.0.6-3.el7.centos                                     
  httpd-tools.x86_64 0:2.4.6-93.el7.centos                                      
  mailcap.noarch 0:2.1.41-2.el7                                                 

Complete!
Removing intermediate container 164240645e39
 ---> 63db91f4fe6a
Step 6/7 : EXPOSE 80/tcp
 ---> Running in 6585da71fc3b
Removing intermediate container 6585da71fc3b
 ---> eb671cf67f52
Step 7/7 : ENTRYPOINT ["/usr/sbin/httpd","-DFOREGROUND"]
 ---> Running in f6e7297025af
Removing intermediate container f6e7297025af
 ---> bac03b20761a
Successfully built bac03b20761a
Successfully tagged myimg:v1.7
[root@node1 test]# docker run --name m1 --rm -it myimg:v1.7 /bin/sh
Usage: /usr/sbin/httpd [-D name] [-d directory] [-f file]
                       [-C "directive"] [-c "directive"]
                       [-k start|restart|graceful|graceful-stop|stop]
                       [-v] [-V] [-h] [-l] [-L] [-t] [-T] [-S] [-X]
Options:
  -D name            : define a name for use in <IfDefine name> directives
  -d directory       : specify an alternate initial ServerRoot
  -f file            : specify an alternate ServerConfigFile
  -C "directive"     : process directive before reading config files
  -c "directive"     : process directive after reading config files
  -e level           : show startup errors of level (see LogLevel)
  -E file            : log startup errors to file
  -v                 : show version number
  -V                 : show compile settings
  -h                 : list available command line options (this page)
  -l                 : list compiled in modules
  -L                 : list available configuration directives
  -t -D DUMP_VHOSTS  : show parsed vhost settings
  -t -D DUMP_RUN_CFG : show parsed run settings
  -S                 : a synonym for -t -D DUMP_VHOSTS -D DUMP_RUN_CFG
  -t -D DUMP_MODULES : show all loaded modules 
  -M                 : a synonym for -t -D DUMP_MODULES
  -t                 : run syntax check for config files
  -T                 : start without DocumentRoot(s) check
  -X                 : debug mode (only one worker, do not detach)
[root@node1 test]# 

  提示:可以看到我們用docker run指定命令去覆蓋ENTRYPOINT指令指定的命令,它給我們打印了httpd命令的用法,這說明我們後面傳遞的/bin/sh 當作參數傳遞給ENTRYPOINT說指定的命令;這裏還需要說一下,上面的示例用docker run 去覆蓋ENTRYPOINT指令指定的命令,沒有報錯的原因應該是busybox里的httpd程序支持傳遞/bin/sh當作參數;

  示例:CMD指令同ENTRYPOINT一起使用

[root@node1 test]# cat Dockerfile 
FROM centos:7

MAINTAINER "qiuhom <qiuhom@linux-1874.com>"

LABEL version="1.0"

LABEL description="this is test file \ that label-values can span multiple lines."

RUN yum install -y httpd

ADD entrypoint.sh /bin/

EXPOSE 80/tcp 

CMD ["/usr/sbin/httpd","-DFOREGROUND"]

ENTRYPOINT ["/bin/entrypoint.sh"]

[root@node1 test]# 

  提示:以上dockerfile使用了CMD和ENTRYPOINT指令來指定容器默認運行程序;此時CMD所指定的命令默認會以參數的形式傳給ENTRYPOINT指令所指定的命令;而上面ENTRYPOINT指定指定的是一個腳本,也就說上面dockerfile最終運行的命令是/bin/entrypoint.sh /usr/sbin/httpd -DFOREGROUND;這裏的腳本就相當於中間層,通過腳本設定一些參數,然後把CMD指定的命令當作參數傳給腳本,最終腳本運行起來;

  entrypoint腳本

[root@node1 test]# ll
total 1032
-rw-r--r-- 1 root root     307 Jun  3 11:28 Dockerfile
-rwxr-xr-x 1 root root     300 Jun  3 11:22 entrypoint.sh
drwxr-xr-x 2 root root      42 May 31 01:51 html
-rw-r--r-- 1 root root 1043748 May 26 11:07 nginx-1.19.0.tar.gz
-rw-r--r-- 1 root root      22 May 31 01:52 test.html
[root@node1 test]# cat entrypoint.sh 
#!/bin/bash

doc_root=${DOC_ROOT:-/var/www/html}
cat > /etc/httpd/conf.d/myweb.conf <<EOF
        <virtualhost *:80>
                servername "localhost"
                documentroot "${doc_root}"
                <directory "${doc_root}">
                        options none
                        allowoverride none
                        require  all granted
                </directory>
        </virtualhost>
EOF

exec "$@"
[root@node1 test]# 

  提示:這個腳本很簡單就是在/etc/httpd/conf.d/生成一個myweb.conf的配置文件,然後最後引用腳本的參數運行;exec “$@” 表示把腳本的所有參數獨立運行成一個守護進程;默認不使用exec就表示以shell子進程的方式運行,exec就表示運行為單獨的守護進程,不再是shell子進程的方式;

  測試:

[root@node1 test]# docker build . -t httpd:v1
Sending build context to Docker daemon  1.051MB
Step 1/9 : FROM centos:7
 ---> b5b4d78bc90c
Step 2/9 : MAINTAINER "qiuhom <qiuhom@linux-1874.com>"
 ---> Using cache
 ---> 604899ef29f9
Step 3/9 : LABEL version="1.0"
 ---> Using cache
 ---> d9edea71fa22
Step 4/9 : LABEL description="this is test file \ that label-values can span multiple lines."
 ---> Using cache
 ---> ee027bbdc04b
Step 5/9 : RUN yum install -y httpd
 ---> Using cache
 ---> 63db91f4fe6a
Step 6/9 : ADD entrypoint.sh /bin/
 ---> 49d1270c3aa3
Step 7/9 : EXPOSE 80/tcp
 ---> Running in 3dacf6acf23b
Removing intermediate container 3dacf6acf23b
 ---> edced77af5b5
Step 8/9 : CMD ["/usr/sbin/httpd","-DFOREGROUND"]
 ---> Running in 23bb32def296
Removing intermediate container 23bb32def296
 ---> 169a5e164ba5
Step 9/9 : ENTRYPOINT ["/bin/entrypoint.sh"]
 ---> Running in f3bf0c267c7b
Removing intermediate container f3bf0c267c7b
 ---> 0801db092665
Successfully built 0801db092665
Successfully tagged httpd:v1
[root@node1 test]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
httpd               v1                  0801db092665        35 seconds ago      307MB
myimg               v1.7                bac03b20761a        12 minutes ago      307MB
myimg               v1.6                5370df4238eb        2 hours ago         1.22MB
myimg               v1.5                5825c2ec655f        2 hours ago         1.22MB
myimg               v1.4                58e3b4c40ae7        2 hours ago         1.22MB
myimg               v1.3                2e296b4f4500        3 hours ago         1.22MB
myimg               v1.2                30a5f5594104        3 hours ago         203MB
myimg               v1.1                ae463ec8cbd9        3 hours ago         203MB
myimg               v1                  7f109a34a4a5        3 hours ago         203MB
busybox             latest              1c35c4412082        19 hours ago        1.22MB
centos              7                   b5b4d78bc90c        4 weeks ago         203MB
[root@node1 test]# docker run --name h1 -d httpd:v1
cee14b04912822c33e7deeee361e1ce0c20d7daf6c0666bff319bf3f1bc69bdc
[root@node1 test]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
cee14b049128        httpd:v1            "/bin/entrypoint.sh …"   9 seconds ago       Up 9 seconds        80/tcp              h1
[root@node1 test]# 

  提示:可以看到我們build成鏡像后,直接運行為容器,容器正常;我們進入容器內部看看它到底運行的說明命令

[root@node1 test]# docker exec -it h1 /bin/bash
[root@cee14b049128 /]# ls /etc/httpd/conf.d/myweb.conf 
/etc/httpd/conf.d/myweb.conf
[root@cee14b049128 /]# cat /etc/httpd/conf.d/myweb.conf
        <virtualhost *:80>
                servername "localhost"
                documentroot "/var/www/html"
                <directory "/var/www/html">
                        options none
                        allowoverride none
                        require  all granted
                </directory>
        </virtualhost>
[root@cee14b049128 /]# ps aux
USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root          1  0.0  0.1 224080  5016 ?        Ss   16:26   0:00 /usr/sbin/httpd -D
apache        7  0.0  0.0 224212  2960 ?        S    16:26   0:00 /usr/sbin/httpd -D
apache        8  0.0  0.0 224212  2960 ?        S    16:26   0:00 /usr/sbin/httpd -D
apache        9  0.0  0.0 224212  2960 ?        S    16:26   0:00 /usr/sbin/httpd -D
apache       10  0.0  0.0 224212  2960 ?        S    16:26   0:00 /usr/sbin/httpd -D
apache       11  0.0  0.0 224212  2960 ?        S    16:26   0:00 /usr/sbin/httpd -D
root         12  0.0  0.0  11828  1932 pts/0    Ss   16:35   0:00 /bin/bash
root         27  0.0  0.0  51756  1720 pts/0    R+   16:36   0:00 ps aux
[root@cee14b049128 /]# httpd -t -D DUMP_VHOSTS
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
VirtualHost configuration:
*:80                   localhost (/etc/httpd/conf.d/myweb.conf:1)
[root@cee14b049128 /]# 

  提示:可以看到容器內部運行的就是/usr/sbin/httpd -DFOREGROUND這個命令;其實這個命令不是CMD直接運行的命令,而是通過腳本獲取參數而來的;我們通過腳本添加的配置文件都在對應的位置,並且也都生效了;總結一點,通常CMD和ENTRYPOINT應用在通過entrypoint腳本做中間層向容器內運行的程序提供配置文件的場景,通常這些應用程序不是雲原生的;

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

※評比南投搬家公司費用收費行情懶人包大公開

搬家價格與搬家費用透明合理,不亂收費。本公司提供下列三種搬家計費方案,由資深專業組長到府估價,替客戶量身規劃選擇最經濟節省的計費方式