欧美vvv,亚洲第一成人在线,亚洲成人欧美日韩在线观看,日本猛少妇猛色XXXXX猛叫

新聞資訊

    近幾年影響最大版本來襲

    2022 年 5 月 3 日,Kubernetes 1.24 正式發布。這個版本的發布可以說是“姍姍來遲”和“萬眾矚目”,因為此次發布對 Kubernetes 社區會帶來深遠影響。

    在 1.24 版本中,共有 46 項功能增強,其中 13 個進入了穩定期,14 個是改進現有的功能,13 個是全新的功能,此外還有六個被廢棄的功能。相信很多了解 Kubernetes 的同學已經知道了,其中最重要的就是 Kubernetes 社區正式移除了對于 Docker 的支持,在經歷了一年多、幾個大版本的過渡期之后,這一天還是到來了。除了這個重大變更以外,其他的新的功能增強也值得我們關注,由于篇幅的限制,在這里就不一一列舉了,筆者先帶大家了解幾個方面,順便也講講博云容器云平臺在這些領域的工作。


    新鮮上架

    1. Docker 的離去

    Docker 和 Kubernetes 互相陪伴,走過了很久,現在是分別的時刻了。

    不久前,Kubernetes 社區發布了一個紀錄片,講述了 Kubernetes 的誕生和發展,其中提到了 Kubernetes 和 Docker 的糾葛,這兩個項目有時幫助,常常競爭,總是合作。但是令人唏噓的是,隨著 Kubernetes 成長為容器編排的事實標準,容器運行時也百花齊放,Kubernetes 社區迫切需要一套統一的標準管理多種容器運行時,因此 CRI 應運而生,而 docker shim 墊片的方式也必將逐漸退出歷史舞臺。

    相比于歷史,大家可能更關心未來怎么辦,盡管 Kubernetes 官方發了幾篇博文向用戶說明即使廢棄 Docker 也不用恐慌,但是很多用戶可能還是不放心。其實 Kubernetes 社區之所以選擇現在這個時間點放棄 Docker,很大的原因是社區中的替代方案基本已經成熟。

    在運行時層面,containerd、cri-o 初露鋒芒;在客戶端命令行工具中 podman,nerdctl 都是非常優秀的工具。以 podman 工具為例,在使用方法上,它與 Docker 十分類似。

    alias docker=podman

    沒錯,可以將 podman 直接當作 Docker 使用,這極大減少了開發者的遷移成本。

    在 CRI 的選擇上,我們的可選項就更多了,由于 Kubernetes 的優秀設計,很容易就可以實現一個 CRI,目前開源社區中的 CRI 實現也很多,比較著名的有 containerd 和 cri-o,了解 Kubernetes 的同學知道,其實 Docker 后端就是調用的 containerd,因為 Docker 和 podman 構建的鏡像都是 OCI 標準的,所以不用擔心現有鏡像的兼容性問題。另外,雖然 docker-shim 被正式移除了,但是 Mirantis (于 19 年底收購 docker 企業部門)維護的 cri-dockerd 項目仍然可以幫助大家實現 Kubernetes 和 Docker 的對接。

    博云容器云平臺很早就開始進行 containerd、cri-o 的兼容工作,目前已經完美適配這兩個 CRI,并且博云容器云平臺的特色產品,裸金屬容器也已經適配了 containerd 和 cri-o。

    隨著 1.24 的發布,可以預期未來的 Kubernetes 部署環境中 Docker 占比會逐漸減少,containerd、cri-o、podman、nerdctl 等運行時和配套工具會逐漸進入大眾視野。Kubernetes 作為容器編排領域多年的事實標準,此次變更對應用運維和部署的影響不大。同時,Docker 作為本次云原生浪潮的起點,在功能、易用性、用戶積累等方面仍然有巨大的優勢,在開發測試、個人使用等場景仍然會長期存在。


    2. Windows 的逐步上位

    容器技術生于 Linux,長于 Linux。雖然微軟也為 Windows 加入了容器功能,但是 Kubernetes 對于 Windows 容器的兼容不盡如人意,很多功能都缺失。

    不過在 1.24 版本中,我們可以看見一些變化,Kubernetes 增強了 Windows 版本的一致性認證標準。這項工作的推進可以使云服務商提供更加穩定、符合 Kubernetes 規范的 Kubernetes 發行版云平臺。

    由于歷史遺留原因,其實有很多大型用戶的業務程序只有 Windows 版本,他們對于 Windows 業務容器化、編排 Windows 容器也有著強烈的需求,所以博云容器云平臺對于 Windows 容器的適配是非常重視的,我們很早就適配了 Windows 系統上的 Kubernetes。

    博云的自研組件,例如 Fabric CNI 也推出了 Windows 版本,相比于 Kubernetes 官方推薦的 Flannel ,Fabric 有著更優秀的性能和更強大的功能

    除此之外,博云容器云平臺對 Windows 集群的計算、存儲、網絡和監控日志都進行了統一管理,可以說在使用體驗上與 Linux 集群沒有多少差別。

    目前已有多個用戶使用了 Windows 版本的博云容器云平臺,實現了運行在 Windows 系統上的業務在幾千核 CPU 規模的集群中穩定高效運行。


    3. 網絡的穩中求進

    網絡一直是 Kubernetes 的重中之重。

    在 1.24 中,Kubernetes 帶來了幾個關于網絡的新功能,其中有兩個值得特別關注

    一是 NetworkPolicy 新增 NetworkPolicyStatus 字段,CNI 通過設置這個字段可以清楚的告訴用戶目前 NetworkPolicy 是否生效

    二是增加了 service 動態和靜態 IP 的預留功能,此功能可以一定程度上防止 IP 沖突。

    博云自研 Fabric CNI 也將在下月發布 2.5 版本,在此版本中帶來了很多新功能,而且也通過目前大熱的 eBPF 技術進一步增強了 Fabric,敬請期待。


    4. Job 的成長

    在最近一兩年,讓 AI, big data, HPC 與 Kubernetes 結合一直是云原生一個有趣的方向,而 Kubernetes 的原生對象 -- Job 是實現這一目的不可或缺的工具,所以在這個版本中,Kubernetes 社區為 Job 和 CronJob 做了很多優化:

    • Cronjob 支持設置時區
    • 暫停 Job 的功能達到穩定狀態
    • 跟蹤 Job 下 pod 狀態的功能達到 beta 狀態
    • 索引作業的功能達到穩定狀態

    這些功能使得 Job 和 Cronjob 更加易用,但是筆者覺得,這些只是餐前小菜。

    真正值得關注的是,在近期,Kubernetes 社區成立了批處理作業工作組,這個工作組可能會為 Kubernetes 原生 Job 在使用方式上帶來新鮮血液,但是目前還需觀望。

    博云算力平臺以 CNCF Volcano 項目為核心調度引擎,為眾多客戶提供了運行 AI、big data、HPC 等業務的土壤,切實解決了眾多行業痛點。


    5. 存儲也不能落下

    在 1.24 版本中,存儲方向也有很多增強,其中值得關注的幾項增強:

    • 增加 CSI 卷運行狀況監控
    • CSI 卷擴展達到穩定狀態
    • 儲存容量跟蹤達到穩定狀態

    在 1.24 中 CSI 卷的運行狀態作為一個 Kubelet 指標被公開,通過這個指標,我們可以更直觀、真實的了解卷的狀態。

    博云在儲存領域也有諸多行動,博云自研開源 CSI -- Carina 已經進入 CNCF 云原生全景圖。歡迎各位開發者來 Carina 社區溝通交流,博云將保持開放的態度歡迎各位開發者的參與(Carina 社區:https://github.com/carina-io/carina)。


    6. 有狀態服務的加速迭代

    有狀態服務一直是 Kubernetes 的特色功能,它體現了 Kubernetes 對各種類型業務的包容態度,使得諸如數據庫等應用也可以很好的運行到 Kubernetes 上來。

    通常在滾動更新時,為了降低丟失應用實例丟失的風險,并且更大限度提高可用性,有狀態服務的 pod 會一次刪除一個,再重建一個。但是這樣速度會很慢。

    在 1.24 版本中,為有狀態服務引入了一個新的字段 maxUnavailable, 通過設置這個字段的值,可以控制 pod 刪除個數,例如將這個值設置為 5,則一次刪除 5 個 pod,再新建 5 個 pod,通過這種方式,可以加快有狀態服務的滾動更新速度。


    結語

    “Kubernetes 1.24 是 2022 年 Kubernetes 更新的第一個版本。在疫情的第三年里,Kubernetes 社區中的貢獻者們始終不懈奉獻,將 Kubernetes 帶到了一個全新的高度。在這個版本中,一如既往的加入了令人眼前一亮的新功能,既有移除 Docker 這樣關鍵性的變更,也有在計算、存儲、網絡層面的增強。在 1.24 版本中,隨著 Kubernetes 的成長,云原生將會有更多可能性值得我們去發掘。”

    博云作為 Kubernetes 社區全球排名第 11 位的貢獻者,長期持續為 Kubernetes 的發展貢獻力量。博云容器云將緊跟技術最新發展,及時完成對 Kubernetes 1.24 版本的支持兼容,并實現對老版本的平滑升級。

    最后,祝愿 Kubernetes 貢獻者和用戶們,能夠像 Kubernetes 1.24 的官方代號 – “觀星者”所描繪的一樣,將目光投向遠方,探索云計算更多的未知領域。


    參考文章:

    https://sysdig.com/blog/kubernetes-1-24-whats-new/

    https://kubernetes.io/zh/docs/tasks/administer-cluster/migrating-from-dockershim/check-if-dockershim-deprecation-affects-you/

    https://kubernetes.io/zh/blog/2022/02/17/dockershim-faq/

    https://kubernetes.io/zh/blog/2022/04/07/upcoming-changes-in-kubernetes-1-24/

    https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.24.md

    https://podman.io/whatis.html

    https://github.com/carina-io/carina

    前言

    為了進一步了解以太坊區塊鏈網絡的工作方式和運行原理,筆者通過官方軟件Geth搭建了私有以太坊網絡fantasynetwork,最終實現了單機和多機節點間的相互連通:首先通過VMware Workstation創建基礎Ubuntu實驗平臺,再安裝Golang1、Geth2等依賴環境;其次使用puppeth工具生成私網的配置文件fantasynetwork.json并復制到三個節點目錄下,三個節點均使用該配置文件初始化網絡;最后使用static-nodes.json的方式將三個節點設為默認接入節點,實現節點間的連通,連通后各節點中的賬戶可以互相轉賬挖礦。

    單機多節點私網3

    本試驗的項目結構為:

    privateNet    
    ├── accounts.txt    
    ├── fantasynetwork.json    
    ├── node1    
    │   ├── geth    
    │   ├── keystore    
    │   ├── node.sh    
    │   ├── password.txt    
    │   └── static-nodes.json    
    ├── node2    
    │   ├── geth    
    │   ├── keystore    
    │   ├── node.sh    
    │   ├── password.txt    
    │   └── static-nodes.json    
    └── node3    
        ├── geth    
        ├── keystore    
        ├── node.sh        
        ├── password.txt    
        └── static-nodes.json

    創建工作目錄

    1. 創建私網工作目錄mkdir privateNet && cd privateNet
    2. 創建三個節點數據目錄mkdir node1 node2 node3
     privateNet/
     ├── node1
     ├── node2
     └── node3

    創建默認用戶

    1. Node1
     test@ubuntu:~/privateNet$ geth --datadir node1/ account new
     Your new account is locked with a password. Please give a password. Do not forget this password.
     Password:
     Repeat password:
    
     Your new key was generated
    
     Public address of the key:   0x600d77B8ce36B829BFC8a1Cc5696Faf2218bDf75
     Path of the secret key file: node1/keystore/UTC--2021-08-11T04-51-26.533482715Z--600d77b8ce36b829bfc8a1cc5696faf2218bdf75

    Node 2

     test@ubuntu:~/privateNet$ geth --datadir node2/ account new
     Your new account is locked with a password. Please give a password. Do not forget this password.
     Password:
     Repeat password:
    
     Your new key was generated
    
     Public address of the key:   0x2F7fD5BD0026f7C2f0dB94b79D58AFE517BC56d2
     Path of the secret key file: node2/keystore/UTC--2021-08-11T04-53-30.820914994Z--2f7fd5bd0026f7c2f0db94b79d58afe517bc56d2

    Node3

     test@ubuntu:~/privateNet$ geth --datadir node3/ account new
     Your new account is locked with a password. Please give a password. Do not forget this password.
     Password:
     Repeat password:
    
     Your new key was generated
    
     Public address of the key:   0x6c1440E9c6Ca93C18B1e2A069D1D5a70e29C2363
     Path of the secret key file: node3/keystore/UTC--2021-08-11T04-54-24.244487186Z--6c1440e9c6ca93c18b1e2a069d1d5a70e29c2363

    在此創建賬戶的密碼設置為fantasy,操作完成后會在每個節點目錄下的keystore目錄中找到賬戶密鑰文件/錢包地址。

    保存賬戶憑證

    1. 將以上賬戶的公鑰地址保存至文本文件
     echo '0x600d77B8ce36B829BFC8a1Cc5696Faf2218bDf75' >> accounts.txt
     echo '0x2F7fD5BD0026f7C2f0dB94b79D58AFE517BC56d2' >> accounts.txt
     echo '0x6c1440E9c6Ca93C18B1e2A069D1D5a70e29C2363' >> accounts.txt

    為了實驗方便,將賬戶對應的密碼文件保存至對應節點目錄下

     echo 'fantasy' > node1/password.txt
     echo 'fantasy' > node2/password.txt
     echo 'fantasy' > node3/password.txt

    創建配置文件

    1. 設置網絡名稱
     test@ubuntu:~/privateNet$ puppeth
     Please specify a network name to administer (no spaces, hyphens or capital letters please)
     > fantasynetwork
     Sweet, you can set this via --network=fantasynetwork next time!
     INFO [08-10|22:08:31.110] Administering Ethereum network           name=fantasynetwork
     WARN [08-10|22:08:31.110] No previous configurations found         path=/home/test/.puppeth/fantasynetwork

    選擇程序功能

     What would you like to do? (default=stats)
     1. Show network stats
     2. Configure new genesis
     3. Track new remote server
     4. Deploy network components
     > 2

    選擇創建網絡

     What would you like to do? (default=create)
     1. Create new genesis from scratch
     2. Import already existing genesis
     > 1

    選擇共識算法

     Which consensus engine to use? (default=clique)
     1. Ethash - proof-of-work
     2. Clique - proof-of-authority
     > 1

    選擇默認賬號

     Which accounts should be pre-funded? (advisable at least one)
     > 0x600d77B8ce36B829BFC8a1Cc5696Faf2218bDf75
     > 0x2F7fD5BD0026f7C2f0dB94b79D58AFE517BC56d2
     > 0x6c1440E9c6Ca93C18B1e2A069D1D5a70e29C2363
     > 0x

    設置默認單位

     Should the precompile-addresses (0x1 .. 0xff) be pre-funded with 1 wei? (advisable yes)
     > yes

    設置網絡ID

     Specify your chain/network ID if you want an explicit one (default=random)
     > 7777
     INFO [08-10|22:16:40.485] Configured new genesis block

    導出配置文件

     What would you like to do? (default=stats)
     1. Show network stats
     2. Manage existing genesis
     3. Track new remote server
     4. Deploy network components
     > 2
     1. Modify existing configurations
     2. Export genesis configurations
     3. Remove genesis configuration
     > 2
     Which folder to save the genesis specs into? (default=current)
     Will create fantasynetwork.json, fantasynetwork-aleth.json, fantasynetwork-harmony.json, fantasynetwork-parity.json
     >
     INFO [08-10|22:18:48.283] Saved native genesis chain spec          path=fantasynetwork.json
     INFO [08-10|22:18:48.285] Saved genesis chain spec                 client=aleth path=fantasynetwork-aleth.json
     INFO [08-10|22:18:48.286] Saved genesis chain spec                 client=parity path=fantasynetwork-parity.json
     INFO [08-10|22:18:48.287] Saved genesis chain spec                 client=harmony path=fantasynetwork-harmony.json

    退出工具

    What would you like to do? (default=stats)
    1. Show network stats
    2. Manage existing genesis
    3. Track new remote server
    4. Deploy network components
    > ^C

    此時可在當前目錄下看見生成的四個配置文件,在此只用到fantasynetwork.json文件,其他文件可刪去。

    1. 修改配置文件 為了更容易挖到礦,將配置文件中difficulty難度值調小(其它參數含義可參考《創世區塊配置文件genesis.json的格式解讀》4):

    初始化三個節點

    每個節點必須使用相同的配置文件進行初始化:

    geth --datadir node1/ init fantasynetwork.json
    geth --datadir node2/ init fantasynetwork.json
    geth --datadir node3/ init fantasynetwork.json

    運行三個節點

    進入對應的節點目錄下執行一下命令(其它參數含義可參考《以太坊客戶端Geth命令用法-參數詳解》5):

    1. Node1
    geth --nousb --datadir=$pwd --syncmode 'full' --port 27271 --miner.gasprice 0 --miner.gastarget 470000000000 --http --http.addr 'localhost' --http.port 7271 --http.api admin,eth,miner,net,txpool,personal,web3 --mine --allow-insecure-unlock --unlock "0x600d77B8ce36B829BFC8a1Cc5696Faf2218bDf75" --password password.txt 

    得到節點一的enode

    enode://0f870fa3f8085f5abf74ea7c2a12a0809a9daaece20e3b1c4c80fb6929ff652681068c6ffd47852a4544dc282a4a15f531b452e05c4f1cf6861d4fb3b728edeb@127.0.0.1:27271

    Node2

    geth --nousb --datadir=$pwd --syncmode 'full' --port 27272 --miner.gasprice 0 --miner.gastarget 470000000000 --http --http.addr 'localhost' --http.port 7272 --http.api admin,eth,miner,net,txpool,personal,web3 --mine --allow-insecure-unlock --unlock "0x2F7fD5BD0026f7C2f0dB94b79D58AFE517BC56d2" --password password.txt 

    得到節點二的enode:

    enode://45c2fc2bfdf0f48afe2083d82cc1cc642a96fcc2815755024a17b95b9fd1b3124f89e186c88a5013ced1c00bd10060a90e6b53e94fdbbfa6098b3088b3f78274@127.0.0.1:27272

    Node3

    geth --nousb --datadir=$pwd --syncmode 'full' --port 27273 --miner.gasprice 0 --miner.gastarget 470000000000 --http --http.addr 'localhost' --http.port 7273 --http.api admin,eth,miner,net,txpool,personal,web3 --mine --allow-insecure-unlock --unlock "0x6c1440E9c6Ca93C18B1e2A069D1D5a70e29C2363" --password password.txt 

    得到節點三的enode:

    enode://ae4b4e18afa6238753e14ca3e99c0858509fc76efee715dd1c8278bbb7eaa5614fdc8b77a82bf7baf128c14ef574cc6701514fbb97780d30c731f7bc82dfd932@127.0.0.1:27273

    連通三個節點

    Geth主要有三種方法連通其它節點:啟動前配置static-nodes.json文件添加節點、啟動時通過--bootnodes添加節點、啟動后在控制臺通過admin.addPeer命令添加節點。在此我們使用第一種方法。

    1. 在工作目錄下創建static-nodes.json
    [       
    "enode://0f870fa3f8085f5abf74ea7c2a12a0809a9daaece20e3b1c4c80fb6929ff652681068c6ffd47852a4544dc282a4a15f531b452e05c4f1cf6861d4fb3b728edeb@127.0.0.1:27271",    
    "enode://45c2fc2bfdf0f48afe2083d82cc1cc642a96fcc2815755024a17b95b9fd1b3124f89e186c88a5013ced1c00bd10060a90e6b53e94fdbbfa6098b3088b3f78274@127.0.0.1:27272",    
    "enode://ae4b4e18afa6238753e14ca3e99c0858509fc76efee715dd1c8278bbb7eaa5614fdc8b77a82bf7baf128c14ef574cc6701514fbb97780d30c731f7bc82dfd932@127.0.0.1:27273"    
    ]  

    將該文件復制到每個節點根目錄下:

    cp static-nodes.json node1/
    cp static-nodes.json node2/
    cp static-nodes.json node3/

    為了簡化啟動,可以創建啟動節點批處理文件

    • node1/node.sh
    nohup geth --nousb --datadir=$pwd --syncmode 'full' --port 27271 --miner.gasprice 0 --miner.gastarget 470000000000 --http --http.addr 'localhost' --http.port 7271 --http.api admin,eth,miner,net,txpool,personal,web3 --mine --allow-insecure-unlock --unlock "0x600d77B8ce36B829BFC8a1Cc5696Faf2218bDf75" --password password.txt &
    echo "Geth started on node 1"

    node2/node.sh

    nohup geth --nousb --datadir=$pwd --syncmode 'full' --port 27272 --miner.gasprice 0 --miner.gastarget 470000000000 --http --http.addr 'localhost' --http.port 7272 --http.api admin,eth,miner,net,txpool,personal,web3 --mine --allow-insecure-unlock --unlock "0x2F7fD5BD0026f7C2f0dB94b79D58AFE517BC56d2" --password password.txt &
    echo "Geth started on node 2"

    node2/node.sh

    nohup geth --nousb --datadir=$pwd --syncmode 'full' --port 27273 --miner.gasprice 0 --miner.gastarget 470000000000 --http --http.addr 'localhost' --http.port 7273 --http.api admin,eth,miner,net,txpool,personal,web3 --mine --allow-insecure-unlock --unlock "0x6c1440E9c6Ca93C18B1e2A069D1D5a70e29C2363" --password password.txt &
    echo "Geth started on node 3"

    啟動各節點

    test@ubuntu:~/privateNet/node1$ sh node.sh
    test@ubuntu:~/privateNet/node2$ sh node.sh
    test@ubuntu:~/privateNet/node3$ sh node.sh

    打開三個終端,使用geth attach命令接入三個節點命令行

    test@ubuntu:~/privateNet/node1$ geth attach geth.ipc
    test@ubuntu:~/privateNet/node2$ geth attach geth.ipc
    test@ubuntu:~/privateNet/node3$ geth attach geth.ipc

    查看已連接節點

    此時各節點已連接完成,每個節點賬戶默認為10個以太幣,各節點賬戶間可自由轉賬和挖礦,需要注意的是轉賬后必須經過挖礦操作才能被寫入區塊鏈。上方法啟動后的程序將會運行在后臺,關閉需通過ps ax | grep geth命令和kill <process id>命令。

    多機多節點私網

    準備

    1. 設置上節Ubuntu虛擬機網絡模式為橋接,且IP設為靜態IP172.25.1.99
    2. Windows的IP設為靜態172.25.1.55

    加入私網

    1. 在Windows下創建文件夾node4,并將fantasynetwork.json復制到其中
    2. 初始化節點4
    C:\Users\Fantasy\Desktop\node4> geth --datadir . init fantasynetwork.json

    新建賬戶

    C:\Users\Fantasy\Desktop\node4>geth -datadir . console
    > personal.newAccount("fantasy")
    WARN [08-11|16:13:32.987] Please remember your password!
    "0xbef61b5754ffaa843cc9199fb9a11aac468134f4"
    > exit

    啟動節點4

    geth --nousb --datadir=. --syncmode "full" --port 27271 --miner.gasprice 0 --miner.gastarget 470000000000 --http --http.addr 0.0.0.0 --http.port 7271 --http.api admin,eth,miner,net,txpool,personal,web3 --mine --allow-insecure-unlock console

    添加節點1

    > net.peerCount
    0
    > admin.addPeer("enode://0f870fa3f8085f5abf74ea7c2a12a0809a9daaece20e3b1c4c80fb6929ff652681068c6ffd47852a4544dc282a4a15f531b452e05c4f1cf6861d4fb3b728edeb@172.25.1.99:27271")
    true
    > net.peerCount
    1

    此時各節點已連接完成,各節點賬戶間可自由轉賬和挖礦,需要注意的是轉賬后必須經過挖礦操作才能被寫入區塊鏈

    注意事項:

    • 很多教程中說不同節點啟動時不能使用相同的端口,那是因為其運行在同一個主機上,這里節點1和節點4運行在不同的端口上,故可以使用相同的端口。
    • 添加節點無效常見原因/解決辦法:admin.addPeer后等一段時間才會生效admin.addPeer時使用的是NAT后公網地址,而公網防火墻通常拒絕異常接入admin.addPeer后開始挖礦增加同步速度簡單的方法是使用上節中的static-nodes.json方法
網站首頁   |    關于我們   |    公司新聞   |    產品方案   |    用戶案例   |    售后服務   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區    電話:010-     郵箱:@126.com

備案號:冀ICP備2024067069號-3 北京科技有限公司版權所有