Minio的使用教程
Minio介紹
Minlo
是一個(gè)基于Apache License v2.0開(kāi)源協(xié)議的對(duì)象存儲(chǔ)服務(wù)。它兼容亞馬遜S3云存儲(chǔ)服務(wù)接口,非常適合于存儲(chǔ)大容量非結(jié)構(gòu)化的數(shù)據(jù),例如圖片、視頻、日志文件、備份數(shù)據(jù)和容器/虛擬機(jī)鏡像等,而一個(gè)對(duì)象文件可以是任意大小,從幾kb到最大5T不等。 對(duì)于中小型企業(yè),如果不選擇存儲(chǔ)上云,那么 MinIO
是個(gè)不錯(cuò)的選擇,麻雀雖小,五臟俱全。當(dāng)然 MinIO
除了直接作為對(duì)象存儲(chǔ)使用,還可以作為云上對(duì)象存儲(chǔ)服務(wù)的網(wǎng)關(guān)層,無(wú)縫對(duì)接到 Amazon S3
等。
優(yōu)點(diǎn):
- 部署簡(jiǎn)單:一個(gè)single二進(jìn)制文件即是一切,還可支持各種平臺(tái)。
- Minio支持海量存儲(chǔ),可按zone擴(kuò)展(原zone不受任何影響),支持單個(gè)對(duì)象最大5TB;
- 兼容Amazon S3接口,充分考慮開(kāi)發(fā)人員的需求和體驗(yàn);
- 讀寫(xiě)性能優(yōu)異
Minio基礎(chǔ)概念
概念名稱 | 對(duì)應(yīng)含義解釋 |
---|---|
Object | 存儲(chǔ)的基本對(duì)象;比如文件、圖片等等 |
Bucket | 用于存儲(chǔ) Object 的邏輯空間;相互之間互相隔離;類似于系統(tǒng)中的頂層文件夾 |
Drive | 即存儲(chǔ)數(shù)據(jù)的磁盤(pán);所有的對(duì)象數(shù)據(jù)都會(huì)存儲(chǔ)在 Drive 里面 |
Set | 即一組 Drive 的集合;分布式部署根據(jù)集群規(guī)模自動(dòng)劃分一個(gè)或多個(gè) Set |
Linux安裝Minio
1.獲取minio安裝包
wget https://dl.min.io/server/minio/release/linux-amd64/archive/minio-20241029160148.0.0-1.x86_64.rpm -O minio.rpm
2.安裝minio
rpm -ivh minio.rpm
Minio配置
1.修改minio服務(wù)配置文件
vim /usr/lib/systemd/system/minio.service
注釋Type、User、Group
修改后的文件如下:
[Unit] Description=MinIO Documentation=https://docs.min.io Wants=network-online.target After=network-online.target AssertFileIsExecutable=/usr/local/bin/minio [Service] #Type=notify WorkingDirectory=/usr/local #User=minio-user #Group=minio-user ProtectProc=invisible EnvironmentFile=-/etc/default/minio ExecStart=/usr/local/bin/minio server $MINIO_OPTS $MINIO_VOLUMES Restart=always LimitNOFILE=1048576 MemoryAccounting=no TasksMax=infinity TimeoutSec=infinity SendSIGKILL=no [Install] WantedBy=multi-user.target
參數(shù)解釋:
AssertFileIsExecutable
:可以在此參數(shù)聲明的配置文件中添加minio服務(wù)啟動(dòng)時(shí)所需一些參數(shù)
ExecStart
:該參數(shù)用于配置Minio服務(wù)的啟動(dòng)命令,其中$MINIO_OPTS
、$MINIO_VOLUMES
,均引用于EnvironmentFile
中的變量。
Restart
:設(shè)置服務(wù)在失敗時(shí)自動(dòng)重啟,這里是always
,意味著總是重啟。
2.配置
1.編寫(xiě)EnvironmentFile中指定路徑下的配置文件
vim /etc/default/minio
MINIO_ROOT_USER=minioadmin
MINIO_ROOT_PASSWORD=minioadmin
MINIO_VOLUMES=/data
MINIO_OPTS="--console-address :9001"
解釋:
MINIO_ROOT_USER
:登錄后臺(tái)管理平臺(tái)的用戶名
MINIO_ROOT_PASSWORD
:登錄后臺(tái)管理平臺(tái)的密碼
MINIO_VOLUMES
:指定數(shù)據(jù)存儲(chǔ)路徑,需確保指定的路徑是存在的
MINIO_OPTS
:指定管理頁(yè)面的地址的端口號(hào)
2.創(chuàng)建minio數(shù)據(jù)存儲(chǔ)路徑
mkdir /data
3.防火墻設(shè)置開(kāi)放端口
#開(kāi)放minio的9000和9001端口
firewall-cmd --zone=public --add-port=9000/tcp --add-port=9001/tcp --permanent
#重新加載防火墻規(guī)則
firewall-cmd --reload
#查看開(kāi)放的端口
firewall-cmd --list-ports
4.讓systemctl檢查配置并重新加載系統(tǒng)服務(wù)的配置文件
systemctl daemon - reload
#設(shè)置minio服務(wù)自啟動(dòng)
systemctl enable minio
#啟動(dòng)minio服務(wù)
systemctl start minio
#查看minio服務(wù)狀態(tài)
systemctl status minio
Minio后臺(tái)管理系統(tǒng)使用
賬號(hào)密碼就是etc/default/minio
文件里面配置的MINIO_ROOT_USER
和MINIO_ROOT_PASSWORD
介紹
存儲(chǔ)桶管理界面介紹
Access Policy:訪問(wèn)策略
- public:允許所有人對(duì)該存儲(chǔ)桶進(jìn)行讀寫(xiě)操作
- private:只允許所有者操作該存儲(chǔ)桶,其他人不能讀寫(xiě)該存儲(chǔ)桶
- custom:自定義存儲(chǔ)桶的訪問(wèn)權(quán)限,如:只允許所有者寫(xiě),但允許所有人讀,自定義訪問(wèn)權(quán)限有格式要求,格式為JSON
Encryption:加密策略,可選值:Disabled、SSE-S3、SSE-KMS
Reported Usage:存儲(chǔ)桶使用情況,即使用的內(nèi)存大小
Quota:配置存儲(chǔ)桶限制的數(shù)據(jù)量
Browse Bucket:瀏覽存儲(chǔ)桶列表
存儲(chǔ)桶列表界面
介紹
Upload File:上傳文件
Upload Folder:上傳文件夾
Refresh:刷新
Download:下載文件
Share:共享圖片(可以設(shè)置共享的連接的時(shí)效性)
Preview:查看圖片
Delete:刪除圖片
Object Info:對(duì)象信息,包含了名稱、大小、上次修改時(shí)間、內(nèi)容類型等等信息
文件上傳
創(chuàng)建
1.創(chuàng)建存儲(chǔ)桶
創(chuàng)建時(shí)可選值
Bucket Name:存儲(chǔ)桶名稱
Versioning:允許在同一鍵下保留同一對(duì)象的多個(gè)版本。
Object Locking:確保一旦對(duì)象存儲(chǔ)在特定的存儲(chǔ)桶中,它們就不能被刪除,這是為了滿足數(shù)據(jù)保留和法律保留的要求。這種特性或策略只能在創(chuàng)建存儲(chǔ)桶的時(shí)候設(shè)置,一旦存儲(chǔ)桶被創(chuàng)建,就不能再對(duì)這個(gè)特性進(jìn)行更改。
Quota:限制存儲(chǔ)桶中的數(shù)據(jù)量。
2.上傳圖片
1.選擇Upload File
2.選擇要上傳的文件
3.上傳后可以看到界面的右上角有文件的上傳進(jìn)度
訪問(wèn)上傳的圖片
訪問(wèn)minio的存儲(chǔ)桶的圖片的url格式就是
http://主機(jī)ip:9000/存儲(chǔ)桶/文件名
首先在存儲(chǔ)桶瀏覽列表復(fù)制存儲(chǔ)桶中文件的路徑
然后再URL打上自己的Minio服務(wù)的主機(jī)IP加上端口號(hào)最后拼接上我們復(fù)制的文件地址
192.168.181.31:9000/test/房間-臥室-1.jpg
訪問(wèn)報(bào)錯(cuò)?
原因分析:因?yàn)槲覀兊拇鎯?chǔ)桶的訪問(wèn)權(quán)限為私有的所以我們?cè)L問(wèn)不了這個(gè)存儲(chǔ)桶中的圖片\文件,所以我們要修改訪問(wèn)權(quán)限
步驟:
1.點(diǎn)擊存儲(chǔ)桶瀏覽列表右上角的設(shè)置
2.編輯存儲(chǔ)桶的訪問(wèn)權(quán)限,我們選擇自定義權(quán)限
再存儲(chǔ)桶管理界面介紹中就介紹到了存儲(chǔ)桶的訪問(wèn)權(quán)限,所以這里我們選擇自定義,權(quán)限為:只允許所有者寫(xiě),但允許所有人讀,但是
自定義訪問(wèn)權(quán)限,需要使用一個(gè)規(guī)定格式的JSON字符串進(jìn)行描述,具體格式可參考官方文檔。
如:允許(Allow
)所有人(*
)讀取(s3:GetObject
)指定桶(test
)的所有內(nèi)容
{ "Statement" : [ { "Action" : "s3:GetObject", "Effect" : "Allow", "Principal" : "*", "Resource" : "arn:aws:s3:::test/*" } ], "Version" : "2012-10-17" }
按照上圖片進(jìn)行配置之后,再去訪問(wèn)圖片,就可以正常訪問(wèn)了
Minio Java SDK使用
Minio提供了多種語(yǔ)言的SDK供開(kāi)發(fā)者使用,具體內(nèi)容可參考官方文檔。
1. 在Spring Boot項(xiàng)目的pom中引入Minio依賴
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>io.minio</groupId> <artifactId>minio</artifactId> <version>8.2.0</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies>
創(chuàng)建一個(gè)類方法測(cè)試,然后執(zhí)行查看是否上傳成功
public class App { public static void main(String[] args) throws IOException, NoSuchAlgorithmException, InvalidKeyException { try { //構(gòu)造MinIO Client MinioClient minioClient = MinioClient.builder() .endpoint("http://192.168.10.101:9000")//填寫(xiě)你的地址 .credentials("minioadmin", "minioadmin")//填寫(xiě)你的賬號(hào)、密碼 .build(); //創(chuàng)建hello-minio桶 boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket("hello-minio").build()); if (!found) { //創(chuàng)建hello-minio桶 minioClient.makeBucket(MakeBucketArgs.builder().bucket("hello-minio").build()); //設(shè)置hello-minio桶的訪問(wèn)權(quán)限 //JDK15之后的特性,三引號(hào) String policy = """ { "Statement" : [ { "Action" : "s3:GetObject", "Effect" : "Allow", "Principal" : "*", "Resource" : "arn:aws:s3:::hello-minio/*" } ], "Version" : "2012-10-17" }"""; minioClient.setBucketPolicy(SetBucketPolicyArgs.builder().bucket("hello-minio").config(policy).build()); } else { System.out.println("Bucket 'hello-minio' already exists."); } //上傳圖片 minioClient.uploadObject( UploadObjectArgs.builder() .bucket("hello-minio") .object("公寓-外觀.jpg") .filename("D:\\workspace\\hello-minio\\src\\main\\resources\\公寓-外觀.jpg") //這個(gè)文件填寫(xiě)你電腦要上傳的圖片的路徑 .build()); System.out.println("上傳成功"); } catch (MinioException e) { System.out.println("Error occurred: " + e); } } }
如果使用的JDK版本不高與15的話可以用這一段代替
String policy = "{\n" + " \"Statement\" : [ {\n" + " \"Action\" : \"s3:GetObject\",\n" + " \"Effect\" : \"Allow\",\n" + " \"Principal\" : \"*\",\n" + " \"Resource\" : \"arn:aws:s3:::hello-minio/*\"\n" + " } ],\n" + " \"Version\" : \"2012-10-17\"\n" + "}";
2. 在application.yml或properties中添加Minio配置參數(shù)
#項(xiàng)目名 server: servlet: context-path: /minioDemo minio: endpoint: http://192.168.181.29:9000 #minio地址 access-key: minioadmin #用戶名 secret-key: minioadmin #密碼 bucket-name: lease #存儲(chǔ)的minio名稱(自定義)
3. 創(chuàng)建Minio配置類和配置參數(shù)類
3.1. 創(chuàng)建配置類MinioConfiguration
@Configuration @EnableConfigurationProperties(MinioProperties.class)//單個(gè)配置參數(shù)類掃描 //@ConfigurationPropertiesScan("com.waitforme.lease.common.minio")掃描一個(gè)路徑下的所有配置參數(shù)類 //@EnableConfigurationProperties、@ConfigurationPropertiesScan兩個(gè)注解的作用都是為了注冊(cè)配置參數(shù)類,根據(jù)需要使用其一即可 public class MinioConfiguration { @Autowired private MinioProperties properties; @Bean public MinioClient minioClient() { return MinioClient .builder() .endpoint(properties.getEndpoint()) .credentials(properties.getAccessKey(), properties.getSecretKey()) .build(); } }
3.2. 創(chuàng)建一個(gè)配置參數(shù)類
因?yàn)榕渲妙愔行枰玫街暗诙教砑拥腗inio的配置參數(shù),所以創(chuàng)建它
@ConfigurationProperties(prefix = "minio") @Data public class MinioProperties { private String endpoint; private String accessKey; private String secretKey; private String bucketName; }
注意:如果出現(xiàn)了如圖的錯(cuò)誤提示,是因?yàn)槟銢](méi)有在配置類中注冊(cè)配置參數(shù)類,所以要先進(jìn)行注冊(cè),在MinioConfiguration
類上加上@EnableConfigurationProperties
或@ConfigurationPropertiesScan
注解進(jìn)行注冊(cè)
4.創(chuàng)建FileService接口及其實(shí)現(xiàn),實(shí)現(xiàn)圖片獲取、上傳、刪除邏輯
service
public interface FileService { //圖片上傳 String upload(MultipartFile file) throws Exception; //獲取圖片列表 List<String> getListObjects() throws Exception; //刪除單個(gè)圖片 Boolean deleteObject(String fileName) throws Exception; }
serviceImpl
@Service("fileService") public class FileServiceImpl implements FileService { @Autowired MinioClient minioClient; @Autowired MinioProperties properties; @Override public String upload(MultipartFile file) throws Exception { boolean bucketExists = minioClient.bucketExists( BucketExistsArgs.builder() .bucket(properties.getBucketName()).build()); if (!bucketExists) { //判斷minio中是否存在我們配置的存儲(chǔ)桶名稱 minioClient.makeBucket(MakeBucketArgs.builder().bucket(properties.getBucketName()).build()); //創(chuàng)建存儲(chǔ)桶 minioClient.setBucketPolicy( SetBucketPolicyArgs.builder() .bucket(properties.getBucketName()) .config(createBucketPolicyConfig(properties.getBucketName())).build()); //為創(chuàng)建的存儲(chǔ)桶設(shè)置訪問(wèn)權(quán)限 } String fileName = UUID.randomUUID() + "-" + file.getOriginalFilename(); //上傳的文件名 minioClient.putObject(PutObjectArgs.builder() .bucket(properties.getBucketName()) //上傳的存儲(chǔ)桶名稱 .stream(file.getInputStream(), file.getSize(), -1) /*上傳的文件,三個(gè)參數(shù)分別表示: 1. 上傳的文件io流 2. 上傳的文件大小 3. -1表示我們確定了自己要上傳的文件大小后,讓minio自己自動(dòng)去分配每次上傳的大小,因?yàn)閙inio不是一次性刪除而是分片上傳*/ .object(fileName) //上傳后的文件名 .contentType(file.getContentType()) //上傳文件類型,通過(guò)file.getContentType獲取,因?yàn)椴辉O(shè)置的話就是steam類型,訪問(wèn)的時(shí)候會(huì)下載圖片,而不是預(yù)覽圖片 .build()); //上傳文件 return String.join("/", properties.getEndpoint(), properties.getBucketName(), fileName); //join方法用于通過(guò)指定一個(gè)分割符,將傳入的的參數(shù)拼接成一串字符,可以傳入多個(gè)參數(shù) } /** * 獲取圖片列表 * @return 返回處理完的圖片數(shù)組列表 * @throws Exception 直接拋出最大的異常類 */ @Override public List<String> getListObjects() throws Exception { List<String> objectNames = new ArrayList<>(); //創(chuàng)建一個(gè)數(shù)組用于存儲(chǔ)獲取到的圖片 Iterable<Result<Item>> results = minioClient.listObjects(ListObjectsArgs.builder() .bucket(properties.getBucketName()) .build()); //獲取指定存儲(chǔ)桶中的圖片列表 for (Result<Item> result : results) { Item item = result.get(); objectNames.add(String.join("/", properties.getEndpoint(), properties.getBucketName(), item.objectName())); //遍歷得到的數(shù)組,并通過(guò)指定為:http://xxx.xxx.xxx.xx:9000/bucketName/fileName.jpg的格式到數(shù)組中 } return objectNames; } /** * 刪除存儲(chǔ)桶中的單個(gè)圖片 * @param fileName 圖片名稱包括后綴 * @return 直接返回ture * @throws Exception */ @Override public Boolean deleteObject(String fileName) throws Exception { minioClient.removeObject(RemoveObjectArgs.builder() .bucket(properties.getBucketName()) .object(fileName) .build()); return true; } /** * @param bucketName 存儲(chǔ)桶名稱 * @return 返回存儲(chǔ)桶的訪問(wèn)權(quán)限JSON字符串 * 返回值表示允許所以人讀取該存儲(chǔ)桶下的所有文件,沒(méi)有設(shè)置寫(xiě)權(quán)限是因?yàn)槟J(rèn)創(chuàng)建人就是寫(xiě)權(quán)限擁有者 * 其中resource中的%s表示占位符,.formatted中的就是占位符的值 */ private String createBucketPolicyConfig(String bucketName) { //三引號(hào)是jdk15添加的新功能 return """ { "Statement" : [ { "Action" : "s3:GetObject", "Effect" : "Allow", "Principal" : "*", "Resource" : "arn:aws:s3:::%s/*" } ], "Version" : "2012-10-17" } """.formatted(bucketName); } }
如果使用的JDK版本低于15可以用這段代替createBucketPolicyConfig方法里面的代碼
private String createBucketPolicyConfig(String bucketName) { String policy = String.format( "{\n" + " \"Statement\" : [ {\n" + " \"Action\" : \"s3:GetObject\",\n" + " \"Effect\" : \"Allow\",\n" + " \"Principal\" : \"*\",\n" + " \"Resource\" : \"arn:aws:s3:::%s/*\"\n" + " } ],\n" + " \"Version\" : \"2012-10-17\"\n" + "}", bucketName); return policy; }
5.創(chuàng)建Controller
@Controller public class MinioController { @Autowired MinioService minioService; @RequestMapping("/upload") public String upload(@RequestParam MultipartFile file, Model model) { try { String url = minioService.upload(file); model.addAttribute("url", url); model.addAttribute("msg", "上傳成功"); } catch (Exception e) { model.addAttribute("msg", "上傳失敗:" + e.getMessage()); } return "redirect:/list"; } @RequestMapping({"/list", ""}) public String getListObjects(Model model) throws Exception { List<String> listObjects = minioService.getListObjects(); model.addAttribute("listObjects", listObjects); model.addAttribute("msg", listObjects == null ? "獲取圖片失敗或是沒(méi)有圖片" : ""); return "index"; } @RequestMapping("/remove") @ResponseBody public Object removeObject(@RequestParam String fileName) { Map map = null; try { Boolean flag = minioService.deleteObject(fileName); map = new HashMap(); map.put("flag", flag); map.put("msg", "刪除成功"); } catch (Exception e) { map.put("msg", "刪除失敗:" + e.getMessage()); return map; } return map; } }
6.在templates中創(chuàng)建index.html頁(yè)面
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <style type="text/css"> ul{ list-style-type: none; } ul>li{ margin: 20px; } </style> <body> <div align="center"> <h1>minio的增刪改查示例</h1> <form th:action="@{/upload}" method="post" enctype="multipart/form-data"> <input type="file" name="file" required> <button type="submit">上傳圖片</button> </form> </div> <div align="center"> <h2 align="center">已上傳的圖片</h2> <ul> <li th:each="object : ${listObjects}"> <img th:src="@{${object}}" alt="11" width="450px" height="230px"> <a href="#" th:onclick="del(this,[[${object}]]);" style="padding-left: 100px">刪除</a> </li> </ul> <p id="msg" style="color: red" align="center">[[${msg}]]</p> </div> </body> <script th:src="@{/js/jquery-1.12.4.js}" type="text/javascript"></script> <script type="text/javascript"> function del(obj, url) { if (confirm("確認(rèn)要?jiǎng)h除嗎?")) { var parts = url.split("/"); var fileName = parts[parts.length - 1]; $.getJSON("remove", "fileName=" + fileName, function (data) { if (data.flag) { $(obj).parents("li").remove(); } $("#msg").html(data.msg); }) } } </script> </html>
然后,在static中創(chuàng)建js
文件夾放入 jquery-1.12.4.js
頁(yè)面效果
遇到的錯(cuò)誤
獲取圖片信息報(bào)錯(cuò)?
報(bào)錯(cuò)原因:因?yàn)槲锢頇C(jī)的請(qǐng)求時(shí)間跟服務(wù)器的時(shí)間相差太大了,簡(jiǎn)單說(shuō)就是要同步一下虛擬機(jī)的時(shí)間
解決步驟:
1.進(jìn)入虛擬機(jī),點(diǎn)擊右上角序號(hào)1,然后點(diǎn)擊root,再點(diǎn)擊賬號(hào)設(shè)置
2.在彈出的窗口中選擇日期和時(shí)間,然后把自動(dòng)設(shè)置日期和時(shí)間、自動(dòng)設(shè)置時(shí)區(qū)打開(kāi),等待時(shí)間與物理機(jī)相同即可
注意:此方案需要有網(wǎng)絡(luò)才能實(shí)現(xiàn)
a標(biāo)簽用th:onclick="|del(this,${object})|"
報(bào)錯(cuò)500?
原因分析:應(yīng)該是thymeleaf
的版本問(wèn)題
解決方案:替換th:onclick="|del(this,${object})|"
為th:onclick="del(this,[[${object}]]);"
<a href="#" th:onclick="del(this,[[${object}]]);" style="padding-left: 100px">刪除</a>
到此這篇關(guān)于Minio的使用的文章就介紹到這了,更多相關(guān)Minio的使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringCloud+RocketMQ實(shí)現(xiàn)分布式事務(wù)的實(shí)踐
分布式事務(wù)已經(jīng)成為了我們的經(jīng)常使用的。所以我們來(lái)一步一步的實(shí)現(xiàn)基于RocketMQ的分布式事務(wù)。感興趣的可以了解一下2021-10-10Java SimpleDateFormat中英文時(shí)間格式化轉(zhuǎn)換詳解
這篇文章主要為大家詳細(xì)介紹了Java SimpleDateFormat中英文時(shí)間格式化轉(zhuǎn)換,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12Struts2返回json格式數(shù)據(jù)代碼實(shí)例
這篇文章主要介紹了Struts2返回json格式數(shù)據(jù)代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04Java中數(shù)組轉(zhuǎn)list的兩種簡(jiǎn)單實(shí)現(xiàn)方式
這篇文章主要介紹了兩種將數(shù)組轉(zhuǎn)換為L(zhǎng)ist的方法,兩種方法分別是使用Arrays.asList()方法和使用ArrayList構(gòu)造函數(shù),文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2025-03-03HotSpot的Java對(duì)象模型之Oop-Klass模型詳解
這篇文章主要介紹了HotSpot的Java對(duì)象模型之Oop-Klass模型詳解,在JVM層面,不僅Java類是對(duì)象,Java 方法也是對(duì)象, 字節(jié)碼常量池也是對(duì)象,一切皆是對(duì)象,JVM使用不同的oop-klass模型來(lái)表示各種不同的對(duì)象,需要的朋友可以參考下2023-08-08SpringBoot大事務(wù)問(wèn)題的常用優(yōu)化方案
大事務(wù)是指運(yùn)行時(shí)間比較長(zhǎng),操作的數(shù)據(jù)比較多的事務(wù)123,大事務(wù)的產(chǎn)生原因包括操作的數(shù)據(jù)比較多、大量的鎖競(jìng)爭(zhēng)、事務(wù)中有其他非數(shù)據(jù)庫(kù)的耗時(shí)操作等,本文給大家總結(jié)了SpringBoot大事務(wù)問(wèn)題的常用優(yōu)化方案,需要的朋友可以參考下2024-04-04springboot多模塊化整合mybatis,mapper自動(dòng)注入失敗問(wèn)題及解決
這篇文章主要介紹了springboot多模塊化整合mybatis,mapper自動(dòng)注入失敗問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01