疫情拖累原油需求 英國石油損失恐達5200億元

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

英國石油公司(BP)今(15日)預警,第2季將承受最多175億美元(約新台幣5200億元)損失。因武漢肺炎(COVID-19)疫情帶來「持續」經濟衝擊,重創全球石油需求。

受疫情影響,英國石油日前才公布裁減1萬個職位的計畫,今天又發布聲明表示,現行季將承受130億到175億美元的非現金資產減值和沖銷。

能源轉型
能源議題
國際新聞
英國
疫情
原油
武漢肺炎
經濟衝擊
疫情看氣候與能源
石油

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

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

台北網頁設計公司這麼多該如何選擇?

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

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

※回頭車貨運收費標準

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

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

法國擬開採莫三比克天然氣 環團批製造氣候炸彈

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

法國石油業巨擘道達爾(Total)正在莫三比克發展開採天然氣的大型計畫,環保組織「地球之友」今(15日)指控法國此舉無異是在當地放置一枚「氣候定時炸彈」。

法新社報導,「地球之友」(Friends of the Earth)一份報告名為「產業的意外之財,莫三比克的詛咒:法國把莫三比克推進氣阱」(A windfall for the industry, a curse for the country: France Thrusts Mozambique into the gas trap)。報告指出,2010年代初在莫三比克的北海岸外海水面下發現巨大的天然氣儲量,開採總投資金額將達600億美元。

「地球之友」指控,「法國這項陰謀是代表法國能源產業與銀行家的經濟利益……迫使另個非洲國家仰賴化石燃料」。

這份報告指出,法國正研擬三個天然氣計畫,「釋放出的溫室氣體可能相當於法國一年溫室氣體排放量的7倍,更是莫三比克目前年排放量的49倍」。

能源議題
能源轉型
國際新聞
法國
天然氣
油氣開採

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

【其他文章推薦】

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

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

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

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

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

※超省錢租車方案

※回頭車貨運收費標準

聯合國環境署:清潔能源是新冠疫情後最具成本效益的投資之一 

摘錄自2020年6月11日聯合國新聞報導

聯合國環境署在6月10日發布的《2020年全球可再生能源投資趨勢》顯示,新型冠狀病毒對化石燃料行業造成嚴重衝擊。而可再生能源比以往更具成本效益,為各國在經濟復甦中優先考慮清潔能源提供機會,使世界更接近實現《巴黎協定》的目標。

報告顯示可再生能源裝機成本創新低,意味著未來,可再生能源領域的投資將實現更高的產能。得益於技術進步、規模經濟和激烈競爭,風能和太陽能的成本不斷下降。2019年下半年,新建太陽能發電廠的電力成本比10年前降低了83%。

環境署執行主任安德森(Inger Andersen)表示,利用可再生能源價格不斷下跌的優勢,將清潔能源置於後疫情時代經濟復甦方案的核心,是應對全球疫情的最佳保險政策。

能源議題
能源轉型
國際新聞
美國
清潔能源
聯合國
可再生能源發電
巴黎協定

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

【其他文章推薦】

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

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

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

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

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

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

※回頭車貨運收費標準

【Spring註解驅動開發】使用@Lazy註解實現懶加載

寫在前面

Spring在啟動時,默認會將單實例bean進行實例化,並加載到Spring容器中。也就是說,單實例bean默認在Spring容器啟動的時候創建對象,並將對象加載到Spring容器中。如果我們需要對某個bean進行延遲加載,我們該如何處理呢?此時,就需要使用到@Lazy註解了。

項目工程源碼已經提交到GitHub:https://github.com/sunshinelyz/spring-annotation

懶加載

懶加載就是Spring容器啟動的時候,先不創建對象,在第一次使用(獲取)bean的時候,創建並使用對象,大家是不是想到了在【設計模式】專題中的單例模式呢?對單例模式不太了解的同學可以猛戳《淺談JAVA設計模式之——單例模式(Singleton)》,也可以查看《設計模式匯總——你需要掌握的23種設計模式都在這兒了!》來系統學習每種設計模式。

非懶加載模式

此時,我們將PersonConfig2類的配置修改成單實例bean,如下所示。

package io.mykit.spring.plugins.register.config;

import io.mykit.spring.bean.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author binghe
 * @version 1.0.0
 * @description 測試@Scope註解設置的作用域
 */
@Configuration
public class PersonConfig2 {
    @Bean("person")
    public Person person(){
        System.out.println("給容器中添加Person....");
        return new Person("binghe002", 18);
    }
}

接下來,在SpringBeanTest類中創建testAnnotationConfig5()方法,如下所示。

@Test
public void testAnnotationConfig5(){
    ApplicationContext context = new AnnotationConfigApplicationContext(PersonConfig2.class);
    System.out.println("IOC容器創建完成");
}

運行SpringBeanTest類中的testAnnotationConfig5()方法,輸出的結果信息如下所示。

給容器中添加Person....
IOC容器創建完成

可以看到,單實例bean在Spring容器啟動的時候就會被創建,並加載到Spring容器中。

懶加載模式

我們在PersonConfig2的person()方法上加上@Lazy註解將Person對象設置為懶加載,如下所示。

package io.mykit.spring.plugins.register.config;

import io.mykit.spring.bean.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;

/**
 * @author binghe
 * @version 1.0.0
 * @description 測試@Scope註解設置的作用域
 */
@Configuration
public class PersonConfig2 {

    @Lazy
    @Bean("person")
    public Person person(){
        System.out.println("給容器中添加Person....");
        return new Person("binghe002", 18);
    }
}

此時,我們再次運行SpringBeanTest類中的testAnnotationConfig5()方法,輸出的結果信息如下所示。

IOC容器創建完成

可以看到,此時,只是打印出了“IOC容器創建完成”,說明此時,只創建了IOC容器,並沒有創建bean對象。

那麼,加上@Lazy註解后,bean是何時創建的呢?我們在SpringBeanTest類中的testAnnotationConfig5()方法中獲取下person對象,如下所示。

@Test
public void testAnnotationConfig5(){
    ApplicationContext context = new AnnotationConfigApplicationContext(PersonConfig2.class);
    System.out.println("IOC容器創建完成");
    Person person = (Person) context.getBean("person");
}

此時,我們再次運行SpringBeanTest類中的testAnnotationConfig5()方法,輸出的結果信息如下所示。

IOC容器創建完成
給容器中添加Person....

說明,我們在獲取bean的時候,創建了bean對象並加載到Spring容器中。

那麼,問題又來了,只是第一次獲取bean的時候創建bean對象嗎?多次獲取會不會創建多個bean對象呢?我們再來完善下測試用例,在在SpringBeanTest類中的testAnnotationConfig5()方法中,再次獲取person對象,並比較兩次獲取的person對象是否相等,如下所示。

IOC容器創建完成
給容器中添加Person....
true

從輸出結果中,可以看出使用@Lazy註解標註后,單實例bean對象只是在第一次從Spring容器中獲取對象時創建,以後每次獲取bean對象時,直接返回創建好的對象。

總結

懶加載,也稱延時加載。僅對單例bean生效。單例bean是在Spring容器啟動的時候加載的,添加@Lazy註解后就會延遲加載,在Spring容器啟動的時候並不會加載,而是在第一次使用此bean的時候才會加載,但當你多次獲取bean的時候不會重複加載,只是在第一次獲取的時候會加載,這不是延遲加載的特性,而是單例Bean的特性。

好了,咱們今天就聊到這兒吧!別忘了給個在看和轉發,讓更多的人看到,一起學習一起進步!!

項目工程源碼已經提交到GitHub:https://github.com/sunshinelyz/spring-annotation

寫在最後

如果覺得文章對你有點幫助,請微信搜索並關注「 冰河技術 」微信公眾號,跟冰河學習Spring註解驅動開發。公眾號回復“spring註解”關鍵字,領取Spring註解驅動開發核心知識圖,讓Spring註解驅動開發不再迷茫。

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

【其他文章推薦】

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

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

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

※超省錢租車方案

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

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

※回頭車貨運收費標準

Zookeeper實現服務註冊/發現

what that?

Zookeeper在分佈式開發中使用頻繁,但許多框架都對其進行了封裝,初學者可能無法較好的理解其工作原理,該文章演示了使用Zookeeper實現服務註冊,服務發現的簡單demo,希望能達到拋磚引玉的效果;

why need RegisterCenter?

之所以需要訪問註冊和服務發現是因為分佈式系統中,服務之間需要相互調用,但若每個服務自己維護一份依賴的服務信息的話,就顯得很麻煩,且自身維護的數據無法保證其實時性,當依賴的服務信息發生變更時,無法及時獲取更新,解決方案就是引入一個註冊中心,服務提供方將自己的信息寫入到註冊中心,服務使用方從註冊中心來獲取服務信息; 如下圖:

client表示服務使用方,server表示服務提供方

實現的效果: 客戶端可自動發現服務信息,當服務狀態發生變化時(上線,下線,更換地址),客戶端可以及時響應變化,效果如下圖:

效果演示

實現

  1. 首先保證Zookeeper以安裝啟動,且可以正常訪問

  2. 創建Maven項目並添加Zookeeper的Java客戶端依賴(注意版本號需>3.6)

    				<dependency>
                <groupId>org.apache.zookeeper</groupId>
                <artifactId>zookeeper</artifactId>
                <version>3.6.1</version>
            </dependency>
    
  3. 編寫服務提供方

    package com.jerry;
    
    import org.apache.zookeeper.CreateMode;
    import org.apache.zookeeper.KeeperException;
    import org.apache.zookeeper.ZooDefs;
    import org.apache.zookeeper.ZooKeeper;
    import org.apache.zookeeper.data.ACL;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.*;
    import java.nio.charset.StandardCharsets;
    import java.util.ArrayList;
    import java.util.Enumeration;
    
    import static java.net.InetAddress.getLocalHost;
    
    public class UserService {
    
        public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
            new UserService().serving();
        }
    
        public void serving() throws IOException, KeeperException, InterruptedException {
            //獲取本機ip地址
            String ip = null;
            Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
            while (networkInterfaces.hasMoreElements()) {
                NetworkInterface ni = (NetworkInterface) networkInterfaces.nextElement();
                Enumeration<InetAddress> nias = ni.getInetAddresses();
                while (nias.hasMoreElements()) {
                    InetAddress ia = (InetAddress) nias.nextElement();
                    if (!ia.isLinkLocalAddress() && !ia.isLoopbackAddress() && ia instanceof Inet4Address) {
                        ip = ia.getHostAddress();
                    }
                }
            }
            int port = 8988;
    
            //啟動服務
            ServerSocket socket = new ServerSocket(port);
            System.out.println("服務器已啟動...");
            //註冊服務
            serverRegister(ip, port);
            //處理請求
            clientHandler(socket);
        }
    
        private void clientHandler(ServerSocket socket) throws IOException {
            while (true) {
                Socket accept = socket.accept();
                InputStream inputStream = accept.getInputStream();
                byte[] barr = new byte[1024];
                while (true) {
                    int size = inputStream.read(barr);
                    if (size == -1) {
                        //System.out.println("客戶端已關閉..");
                        accept.close();
                        break;
                    }
                    String s = new String(barr, 0, size);
                    //輸出客戶端消息
                    System.out.println(accept.getInetAddress().getHostAddress() + ": " + s);
                }
            }
    
        }
    
        private void serverRegister(String ip, int port) throws IOException, KeeperException, InterruptedException {
            //註冊服務
            ZooKeeper zooKeeper = new ZooKeeper("10.211.55.4: 2181",3000, null);
            try {
                ArrayList<ACL> acl = new ArrayList<>();
                acl.add(new ACL(31, ZooDefs.Ids.ANYONE_ID_UNSAFE));
                zooKeeper.create("/userServer", (ip + ":" + port).getBytes(StandardCharsets.UTF_8), acl, CreateMode.EPHEMERAL);
                System.out.println("服務發布成功!");
            } catch (KeeperException | InterruptedException e) {
                e.printStackTrace();
                throw e;
            }
        }
    }
    
  4. 編寫服務服務使用方

    package com.yyh;
    
    import org.apache.zookeeper.*;
    
    import java.io.IOException;
    import java.io.OutputStream;
    import java.net.InetSocketAddress;
    import java.net.Socket;
    import java.util.Scanner;
    
    public class UserClient implements Watcher {
        String node = "/userServer"; //服務信息所在的節點 服務提供方和服務消費方一致
        private ZooKeeper zooKeeper;
        String server_ip;
        int server_port;
    
        public static void main(String[] args) throws Exception {
            //開始服務監聽
            UserClient userClient = new UserClient();
            userClient.run();
            //當訪問可用時與服務交互
            Scanner scanner = new Scanner(System.in);
            while (true){
                System.out.println("輸入要發送的信息(e:退出)");
                String text = scanner.next();
                if (text.equals("e"))System.exit(-1);
                if (userClient.server_ip == null){
                    System.err.println("沒有可用的服務...");
                }else {
                    userClient.sendToServer(text);
                }
            }
        }
        
        private void run() throws Exception {
            //連接zookeeper
            zooKeeper = new ZooKeeper("10.211.55.4:2181", 3000, null);
            //嘗試獲取服務信息
            getServerInfo();
            //添加對服務信息的永久監聽
            zooKeeper.addWatch(node,this,AddWatchMode.PERSISTENT);
        }
    
        //獲取服務信息
        private void getServerInfo()  {
            try {
                byte[] data = zooKeeper.getData(node, false, null);
                String[] infos = new String(data).split(":");
                server_ip = infos[0];
                server_port = Integer.parseInt(infos[1]);
                System.out.println("獲取服務信息成功!");
                System.out.println(server_ip+":"+ server_port);
            } catch (KeeperException e) {
                System.err.println("服務信息不存在! 等待服務上線........");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
        //當節點狀態發送變化時將執行該方法(通知處理)
        @Override
        public void process(WatchedEvent event) {
            if (event.getPath().equals(node)) {
                //根據具體邏輯處理不同的事件類型,此處只關心節點的創建刪除和更新
                if (event.getType() == Event.EventType.NodeCreated) {
                    System.err.println("服務上線了");
                    getServerInfo();
                } else if (event.getType() == Event.EventType.NodeDataChanged) {
                    System.err.println("服務更新了");
                    getServerInfo();
                }else if (event.getType()== Event.EventType.NodeDeleted){
                    server_ip = null;
                    server_port = 0;
                    System.err.println("服務下線了");
                }
            }
        }
    
        public void sendToServer(String text) {
            InetSocketAddress server_address = new InetSocketAddress(server_ip, server_port);
            Socket socket = new Socket();
            try {
                socket.connect(server_address);
                //System.out.println("連接服務器成功!");
                OutputStream outputStream = socket.getOutputStream();
                outputStream.write(text.getBytes());
                System.out.println("消息發送成功!");
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
  5. 打包服務端代碼,該步驟可忽略,僅為了測試客戶端正確性, 為了在打包時附帶其全部依賴,此處藉助Spring的打包插件,在pom中添加以下內容:

    		<build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <version>1.5.6.RELEASE</version>
                    <executions>
                        <execution>
                            <goals>
                                <goal>repackage</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    

    注意:Spring-boot打包插件會自動獲取項目中的主函數,必須保證主函數只有一個,所以需要暫時註釋客戶端的主函數,最後執行maven的package,得到jar包

  6. 將jar上傳至虛擬機並運行

    java -jar ZookeeperTest-1.0-SNAPSHOT.jar
    

    若沒有其他問題則客戶端依然可以正常連接服務器發送消息;

以上便是使用Zookeeper實現服務註冊和服務發現的具體步驟,在實際開發中,我們可能還會將提供的服務部署為集群,這時可將集群中的各個服務信息作為子節點註冊到指定節點下,客戶端監聽該節點變化,獲取子節點列表從而獲取到服務列表,還可以在此基礎上加上負載均衡算法實現對服務列表的合理訪問; 如圖:

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

【其他文章推薦】

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

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

※超省錢租車方案

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

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

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

台中搬家遵守搬運三大原則,讓您的家具不再被破壞!

Dubbo+Zookeeper集群案例

一.開源分佈式服務框架

1.Dubbo是阿里巴巴公司開源的一個高性能優秀的服務框架,使得應用可通過高性能的 RPC 實現服務的輸出和輸入功能,可以Spring框架無縫集成。
   Dubbo是一款高性能、輕量級的開源Java RPC框架,它提供了三大核心能力:①面向接口的遠程方法調用;②智能容錯和負載均衡;③服務自動註冊和發現

2.結構圖

節點角色說明:

Provider: 暴露服務的服務提供方。
Consumer: 調用遠程服務的服務消費方。
Registry: 服務註冊與發現的註冊中心。
Monitor: 統計服務的調用次數和調用時間的監控中心。
Container: 服務運行容器。
 

調用關係說明

0服務容器負責啟動,加載,運行服務提供者provider。
1服務提供者provider在啟動時,(通過連接服務器的client)向註冊中心註冊自己可以提供的服務。(其實就是註冊一些provider自己的ip:port以及對自己提供的服務的描述,比如能幹什麼!)
2服務消費者consumer在啟動時,向註冊中心訂閱自己所需的服務。並註冊自己的ip:port等信息。
3註冊中心返回服務提供者provider地址列表給消費者consumer,如果有變更,註冊中心將基於長連接推送變更數據給消費者consumer。
4服務消費者consumer,從註冊中心返回的提供者provider地址列表中,基於軟負載均衡算法,選一台提供者provider進行調用,如果調用失敗,再選另一台調用。
5服務消費者consumer和提供者provider,在內存中累計調用次數和調用時間,定時每分鐘發送一次統計數據到監控中心monitor。
Dubbo 架構具有以下幾個特點,分別是連通性、健壯性、伸縮性、以及向未來架構的升級性。

二.Dubbo作用

  dubbo其實就是一个中間層管理工具,他是一個框架,裏面可以裝你想裝的服務,一般註冊中心大多用zookeeper,當然除了zookeeper,還要Redis等也可以做註冊中心。  
 

三.Dubbo+Zookeeper(註冊中心使用Zookeeper),Zookeeper其實是樹狀結構。

1.可以把register理解成房產中介,provider是賣房的人,張三想賣掉自己在秦淮區的學區房,李四想賣掉自己在棲霞區的學區房,consumer王五是想在棲霞區買學區房給自己孩子上學,王五去中介諮詢后,中介返回給王五的需求 滿足者是李四,王五從中介那得到李四的電話,自己打電話找李四買房。

比如Provider註冊的是  192.168.1.(描述121是吃飯,122睡覺,123打遊戲,124健身四種不同的服務)
2-0、 、dubbo–這是dubbo在ZooKeeper上創建的根節點  /dubbo
2-1 、 Dubbo在Zookeeper上註冊的節點目錄:假設接口名稱是:com.bob.dubbo.service.CityDubboService。
這是服務節點,代表了Dubbo的一個服務  /dubbo/com.bob.dubbo.service.CityDubboService
2-2 、 Dubbo啟動時,Consumer和Provider都會把自身的URL格式化為字符串,然後註冊到zookeeper相應節點下,作為一個臨時節點,當連斷開時,節點被刪除。
這是服務提供者的根節點,其子節點代表了每一個服務真正的提供者/dubbo/com.bob.dubbo.service.CityDubboService/providers
這是服務消費者的根節點,其子節點代表每一個服務真正的消費者;/dubbo/com.bob.dubbo.service.CityDubboService/consumers
2-3、 Consumer在啟動時,不僅僅會註冊自身到 …/consumers/目錄下,同時還會訂閱…/providers目錄下所有子節點,具體的看你訂閱具體是哪一個節點(比如訂閱健身這些服務),實時獲取其上Provider的URL字符串信息。register返回給Consumer這個ip–192.168.1.124,Consumer拿着這個iP直接去找Provider調用這項服務–健身。
2-4 、監控中心啟動時訂閱com.bob.dubbo.service.CityDubboService目錄下的所有提供者和消費者URL。

 

四.Dubbo——Zookeeper補充:

支持以下功能:

 
當提供者出現斷電等異常停機時,註冊中心能自動刪除提供者信息
當註冊中心重啟時,能自動恢復註冊數據,以及訂閱請求
當會話過期時,能自動恢復註冊數據,以及訂閱請求
當設置<dubbo:registry check=”false” />時,記錄失敗註冊和訂閱請求,後台定時重試
可通過設置<dubbo:registry username=”admin” password=”124″ />設置zookeeper 登錄信息
可通過<dubbo:registry group=”dubbo” />設置 zookeeper 的根節點,不設置將使用無 根樹
支持 * 號通配符 <dubbo:redistry group=”*” version=”*” />,可訂閱服務的所有分組 和所有版本的提供者
 
補充:
  消費者從ZK獲取provider地址列表后,會在本地緩存一份。當ZK註冊中心所有節點全部宕掉之後,消費者可以使用本地緩存的服務列表和provider進行通信。
ZK的意義在於為consumer和provider提供服務地址的發布/訂閱服務,讓消費者及時感知最新的服務列表,consumer真正調用provider是通過某種通信協議直接調用,並不依賴ZK。
 
所以當zookeeper宕機之後,不會影響消費者調用服務提供者,影響的是zookeeper宕機之後如果提供者有變動,增加或者減少,zk無法把變更通知推送給consumer,consumer會因為感知不到變更時間,不去拉取最新的服務列表,導致本地緩存的服務列表有可能過時的。

完結,個人理解,如有偏差,請大家指正,謝謝!

2020-06-09 10:58:28

 

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

【其他文章推薦】

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

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

※回頭車貨運收費標準

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

※超省錢租車方案

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

※推薦台中搬家公司優質服務,可到府估價

Kubernetes內部域名解析的那些事兒

前言

    在kubernets環境中,服務發現大都是基於內部域名的方式。那麼就涉及到內部域名的解析。從1.11版本開始,kubeadm已經使用第三方的CoreDNS替換官方的kubedns作為集群內部域名的解析組件。

kubernets中的4種DNS策略

None

表示空的DNS設置,這種方式一般用於想要自定義 DNS 配置的場景,往往需要和 dnsConfig 配合一起使用達到自定義 DNS 的目的。

Default

此種方式是讓kubelet來決定使用何種DNS策略。而kubelet默認的方式,就是使用宿主機的/etc/resolv.conf文件。

同時,kubelet也可以配置指定的DNS策略文件,使用kubelet參數即可,如:–resolv-conf=/etc/resolv.conf

ClusterFirst

此種方式是使用kubernets集群內部中的kubedns或coredns服務進行域名解析。若解析不成功,才會使用宿主機的DNS配置來進行解析。

ClusterFistWithHostNet

在某些場景下,我們的 POD 是用 HOST 模式啟動的(HOST模式,是共享宿主機網絡的),一旦用 HOST 模式,表示這個 POD 中的所有容器,都要使用宿主機的 /etc/resolv.conf 配置進行DNS查詢,但如果你想使用了 HOST 模式,還繼續使用 Kubernetes 的DNS服務,那就將 dnsPolicy 設置為 ClusterFirstWithHostNet。

策略配置示例

DNS策略,需要在Pod,或者Deployment、RC等資源中,設置 dnsPolicy 即可,以 Pod 為例:

apiVersion: v1
kind: Pod
metadata:
   labels:
    name: cadvisor-nodexxxx
    hostip: 192.168.x.x
  name: cadvisor-nodexxxx
  namespace: monitoring
spec:
  containers:
  - args:
    - --profiling
    - --housekeeping_interval=10s
    - --storage_duration=1m0s
    image: google/cadvisor:latest
    name: cadvisor-nodexxxx
    ports:
    - containerPort: 8080
      name: http
      protocol: TCP
    resources: {}
    securityContext:
      privileged: true
    terminationMessagePath: /dev/termination-log
    terminationMessagePolicy: File
  dnsPolicy: ClusterFirst
  nodeName: nodexxxx

kubernets中域名解析流程

# Pod中的resolv.conf的解析配置

[root@l-k8s01 ~]# kubectl exec -it nginx-deploy-5754944d6c-dtzpj cat /etc/resolv.conf

nameserver 10.96.0.2
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

[root@l-k8s01 ~]# kubectl get svc -n kube-system |grep dns

kube-dns   ClusterIP  10.96.0.2   <none>   53/UDP,53/TCP,9153/TCP   158d

a)文件中配置的 nameserver 一般是k8s集群內部的dns服務的ClusterIP,無法ping,但是可以訪問。

b)意味着集群Pod內部的所有域名的解析,都要經過kubedns的虛擬ip 10.96.0.2 進行解析。

c)resolv.conf中search域分別是default.svc.cluster.local svc.cluster.local cluster.local,在kubernets中,域名的全稱必須是 service-name.namespace.svc.cluster.local 。

d)假如集群中有一個svc(Service)名為a,在某個Pod中執行命令 curl a 時,在此Pod中會根據/etc/resolv.conf進行解析流程。選擇nameserver 10.96.0.2進行解析,將字符串’a’帶入到/etc/resolv.conf文件中不同的search域,依次進行查找,如下:

a.default.svc.cluster.local -> a.svc.cluster.local -> a.cluster.local

先查找 a.default.svc.cluster.local ,若找不到,則再查找 a.svc.cluster.local ,依次往下進行,直到找到為止。

curl效率分析

在集群中若存在一個名為a的svc,在Pod中curl a和curl a.default都能實現請求,那麼兩種方式哪個的效率高呢?

那肯定是curl a啦,因為發起此請求時,通過/etc/resolv.conf中第一列的search域就能直接找到 a.default.svc.cluster.local ,直接避免了下一級的查找。

容器中訪問外部域名講述

下文將通過示例說明Pod訪問外部域名時發起的相應的請求信息。

以請求baidu.com為例,因為DNS容器一般不具備bash,所以無法通過docker exec的方式進入容器抓包,所以此處採用 進入到DNS容器的網絡中(不是發起DNS請求的容器)的姿勢去抓包,抓包姿勢準備好后,同時在某容器中訪問baidu.com,即可看到在進行的DNS查找的過程中都產生了什麼樣的數據包。

 

### 實操

# 進入dns容器網絡,準備好抓包姿勢

# 查看Pod所在具體的node節點

[root@master1 ~]# kubectl get pods -n kube-system -o wide|grep dns

coredns-5c48579f88-8wprg  1/1   Running  16    30d   10.244.4.120   node1
coredns-5c48579f88-rsnpr   1/1   Running   0     30d   10.244.5.142   node2

# 這裏以node1上的容器為操作對象,所以到node1節點上進行操作

# 找到容器並打印對應的NS ID

[root@node1 ~]# docker ps |grep dns

a964bbb43534 c0f6e815079e "/coredns -conf /etc…" 2 days ago Up 2 days k8s_coredns_coredns-5c48579f88-8wprg_kube-system_b1e7f3c3-98eb-4843-b156-1d203f98bd74_16
fbd12d2f9c7c k8s.gcr.io/pause:3.1 "/pause" 5 days ago Up 5 days k8s_POD_coredns-5c48579f88-8wprg_kube-system_b1e7f3c3-98eb-4843-b156-1d203f98bd74_3

[root@node1 ~]# docker inspect –format “{{.State.Pid}}”  a964bbb43534

21617

# 進入此容器的網絡Namespace

[root@node1 ~]# nsenter -n -t 21617

# 抓包姿勢就緒

[root@node1 ~]# tcpdump -i eth0 udp dst port 53|grep ‘baidu.com’

 

# 在另外的某容器中,進行域名查找操作

說明:一般pod中沒有nslookup命令,故需要手動安裝,根據不同環境自選以下操作。

### Centos

]# cat /etc/redhat-release

CentOS Linux release 7.5.1804 (Core)

]# yum -y install bind-utils

### Debian

# cat /etc/issue

Debian GNU/Linux 9

# apt-get install dnsutils -y

root@jenkins-7d66bf7977-cm4x4:~# nslookup baidu.com 10.244.4.120

 

注意:10.244.4.120是node1上的dns pod在kubernets集群中的內部通信ip地址。因為環境中有兩個dns pod,將其指定要單個具體的容器,能夠使抓包數據完整。

 

# 隨後,在前面就緒的抓包姿勢窗口就能看到數據包的出現

[root@node1 ~]# tcpdump -i eth0 udp dst port 53|grep ‘baidu.com’

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
16:57:50.791154 IP 10.244.4.127.51794 > node1.domain: 55406+ A? baidu.com.infra.svc.cluster.local. (51)
16:57:50.792540 IP 10.244.4.127.56306 > node1.domain: 27958+ A? baidu.com.svc.cluster.local. (45)
16:57:50.793439 IP 10.244.4.127.59799 > node1.domain: 27048+ A? baidu.com.cluster.local. (41)
16:57:50.799463 IP 10.244.4.127.39116 > node1.domain: 2303+ A? baidu.com. (27)

說明:

a)數據包中显示的 infra 是執行nslookup的pod的NameSpace;

b)根據數據显示,在真正解析到 baidu.com 之前,經歷了baidu.com.infra.svc.cluster.local. > baidu.com.svc.cluster.local. > baidu.com.cluster.local. 三次DNS請求。

請求浪費的原因

上文在正確請求到baidu.com之前,有過三次無效請求,即意味着請求浪費,那為什麼會出現那種情況呢,請繼續往下看。

 

# Pod中的resolv.conf的解析配置

root@jenkins-7d66bf7977-cm4x4:/# cat /etc/resolv.conf
nameserver 10.96.0.2
search infra.svc.cluster.local svc.cluster.local cluster.local host.com
options ndots:5

 

# options ndots:5 解釋

如果查詢的域名包含的點”.”,不到5個,那麼進行DNS查找,將使用非完全限定名稱(或者叫絕對域名),如果你查詢的域名包含點數大於等於5,那麼DNS查詢,默認會使用絕對域名進行查詢。

如果我們請求的域名是,a.b.c.d.e,這個域名中有4個點,那麼容器中進行DNS請求時,會使用非絕對域名進行查找,使用非絕對域名,會按照 /etc/resolv.conf 中的 search 域,走一遍追加匹配:

a.b.c.d.e.cicd.svc.cluster.local. ->

a.b.c.d.e.svc.cluster.local. ->

a.b.c.d.e.cluster.local.

直到找到為止。如果走完了search域還找不到,則使用 a.b.c.d.e. ,作為絕對域名進行DNS查找。

 

說明:

a)請求域名中點數少於5個時,先走search域,最後將其視為絕對域名進行查詢;

b)請求域名中點數大於等於5個時,直接視為絕對域名進行查找,只有當查詢不到的時候,才繼續走 search 域。

優化請求浪費

使用全限定域名

當訪問某域名時,以 ‘.’ 為後綴,即使用 完全限定域名(絕對域名),這樣發起的域名請求時將不會走search域進行匹配,而是直接使用整個原始域名字符串為個體進行解析。

 

如:

nslookup baidu.com.

配置特定ndots

在kubernets中,ndots值默認是5。是因為,Kubernetes 認為,內部域名,最長為5,要保證內部域名的請求,優先走集群內部的DNS,而不是將內部域名的DNS解析請求,有打到外網的機會,Kubernetes 設置 ndots 為5是一個比較合理的行為。

如果有特定業務需求,也可配置ndots,如下:

apiVersion: v1
kind: Pod
metadata:
  namespace: default
  name: dns-example
spec:
  containers:
    - name: test
      image: nginx
  dnsConfig:
    options:
      - name: ndots
        value: "1"

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

【其他文章推薦】

※超省錢租車方案

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

※回頭車貨運收費標準

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

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

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

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

“節氣門”聽得多 “氣門”又是干什麼的?

而上述的16V發動機則是相對於之前8v發動機而言,一台8V的四缸發動機意味着每個氣缸兩個氣門,一個進氣門和一個排氣門,如果你現在在紙上畫一個圓,然後再從圓裏面取等大的圓,結果肯定是取的等大的圓越多,取出來總面積越大。

就在汽車越來越同質化的現在,連尾標也不如以前豐富,美國車競爭最激烈的時候,車內有一個CD機都要在尾標炫耀,而車主在路上碰到同款也會下意識看下他的尾標,是不是有帶電動車窗,現在除了花樣頗多的動力表示,僅僅只有各自的看家技術會單獨掛出來。

而國內汽車的尾標,說到當年愛麗舍上的16V尾標有多少朋友會有印象呢?

要是你當時還是個熊孩子可能會以為是一道沒出完的數學題。

要是你那會剛剛上了物理課,可能會以為這是代表着16V的電源。

其實這裏的V是氣門(valve)的簡稱。

我們都知道四衝程發動機的做工過程分別是吸氣,壓縮,做功,排氣。

從中也可以看出氣門的重要性,如果簡單把發動機比作人的話,那麼進氣量和排氣量就等同於我們人的肺活量,肺活量越高肯定運動能力更強。

像下面的入門玩家。

中等玩家。

高級玩家。

而上述的16V發動機則是相對於之前8v發動機而言,一台8V的四缸發動機意味着每個氣缸兩個氣門,一個進氣門和一個排氣門,如果你現在在紙上畫一個圓,然後再從圓裏面取等大的圓,結果肯定是取的等大的圓越多,取出來總面積越大。

所以單缸四氣門的“肺活量”肯定大於兩個氣門的發動機。

那照這樣說氣門越多越好咯,理論上是這樣,所以 以前還有單缸五個氣門的發動機。像法拉利的355。

其型號就表明了該身份,3.5L排量的發動機,每個氣缸5氣門。

而更接近生活的還有國內就有的捷達王20V(氣門為3進兩出)。

當時所有開過的人對這輛車的印象就是兩個字,好開。畢竟多了一肛。

說得那麼好為什麼現在基本上都是每個氣缸4氣門呢,捷達王的20V那麼好開為什麼沒有繼續發展呢?

我們下期再來聊發動機另外一個關鍵的東西,“凸輪軸“。

本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

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

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

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

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

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

奔馳將推史上最強E級,AMG E63 Coupe橫空出世!

新E級CoupeC級CoupeS級Coupe內飾延續了E級轎車的整體布局,不過在風格上則更為年輕,運動,如碳纖維中控飾板,渦輪式出風口,無邊框車門以及全新設計的運動座椅。值得一提的是,先前透露的新E級Coupe 220d,200,300,400 4MATIC只是首發版本,而最令人期待的,則是這一代E級Coupe將確定推出AMG E63版本。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

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

※台北網頁設計公司全省服務真心推薦

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

※推薦評價好的iphone維修中心

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

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

這個配置能“防出軌” 15萬選這些家用車最放心

車身尺寸為4675*1780*1500mm,軸距達到了2710mm,乘坐空間上是比較寬敞的,加上柔軟的座椅,舒適性表現出色。動力方面,提供了1。2T和1。6T兩款發動機可選,匹配5擋手動或者6擋手自一體變速器,沉穩線性的油門調校讓動力非常容易掌控,動力總體表現出色。

隨着上個月的“超級丹”出軌事件后

辛辛苦苦塑造的男神形象毀於一旦

當然,更重要的是有媳婦的人被看得更緊了

上街口買串魚蛋都要向老婆申請

當然這隻是調侃一下

畢竟出軌並不是什麼好事情

但是隨着科技的發展

一種叫“車道偏離預警系統”的東西出現了

裝配在汽車上能有效提升行駛安全性

其工作原理是這樣的:在駕駛員未打轉向燈的情況下,電腦檢測到車輛偏離原車道之後,發出警報,以方向盤震動、發出警示音提醒等多種途徑提醒駕駛員,讓駕駛員及時糾正放向,有效減小事故的發生,哪些車上都有這種配置了,以下幾款15萬左右的合資車就有了。

北京現代-領動

指導價:9.98-15.18萬

一說起韓國品牌,就不得不提那大膽設計的外觀了,領動的設計是比較激進的,視覺衝擊力極強,狹長的大燈造型和碩大的六邊形中網給人留下很深刻的印象;純黑的內飾搭配紅色縫線整體感覺非常運動,中控液晶屏幕支持Carplay和CarLife功能,配置上很豐富,旗艦型車型上甚至裝備了主動安全系統。

2700mm的軸距為其乘坐空間提供了保證,462L的後備箱容積和可4/6比例放倒的後排座椅都能滿足日常使用的需求;其中1.4T車型採用了缸內直噴技術,最大功率為130馬力,搭配7速雙離合變速箱,動力的輸出也相對線性,對於渦輪遲滯的控制很好,幾乎感覺不到什麼遲滯現象。

東風雪鐵龍-雪鐵龍C4L

指導價:13.19-18.99萬

新款C4L的前臉變化是很明顯的,採用了上下橫貫式的進氣格柵,從雙立人車標延伸出來的鍍鉻飾條融入大燈內,看起來相當科幻前衛;內飾的變化卻沒外觀來的那麼強烈,與現款相差無幾,一些細節和配置上的升級更人性化了,电子手剎和全新樣式的換擋桿,操作起來更加方便順手了。

車身尺寸為4675*1780*1500mm,軸距達到了2710mm,乘坐空間上是比較寬敞的,加上柔軟的座椅,舒適性表現出色;動力方面,提供了1.2T和1.6T兩款發動機可選,匹配5擋手動或者6擋手自一體變速器,沉穩線性的油門調校讓動力非常容易掌控,動力總體表現出色。

東風本田-思域

指導價:11.59-16.99萬

思域整車採用全新的家族式設計語言打造,相比老款車型更具肌肉感,更多曲麵線條的運用,讓它在外觀方面更加飽滿立體,運動氣息很濃厚;內飾也是一改以往本田的風格,階梯狀設計的中控台錯落有致,大量的軟質材料覆蓋件也提高了不少檔次感,中央液晶儀錶盤功能豐富,显示效果出色。

2700mm的軸距使得新思域的空間有所改善,乘坐空間令人滿意,儲物空間也是比較多,半封閉的中央扶手箱是其中的亮點;1.5T發動機最大功率177馬力,搭配CVT變速器,起步輕盈暢快,動力輸出一氣呵成,渦輪介入感極其輕微,給人加速很線性的體驗,可以說這代思域迎來了脫胎換骨的一代。

總結:三款車的類型各有特色,適合的人群也更廣,配置豐富外觀帥氣的領動,底盤沉穩操控感好的雪鐵龍C4L,動力強勁高顏值的思域,到底哪個才是你的菜!本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

台北網頁設計公司這麼多該如何選擇?

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

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

※回頭車貨運收費標準

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

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