Java主流分布式解决方案多场景设计与实战(完结26章)
时间:2023-12-21
大小:3.22KB
阅读数:153
查看他发布的资源
资料介绍
目前主流的Java分布式框架有哪些,学起来难不难?
Java的框架主要有:SpringMVC、Spring、Mybatis、Dubbo、Maven、RabbitMQ、Log4j、Ehcache、Redis、Shiro等等
今天就给大家讲讲关于Java主流分布式的一些解决方法,内容包括:JVM锁和MySql锁解决库存超卖问题、基于Redisson框架实现分布式锁及实战&源码深入剖析、基于ZooKeeper实现分布式锁、分布式存储系统Etcd实现分布式锁、实现分布式锁通用SDK与集成、七种分布式事务解决方案、分布式事务Seata框架深入剖析、分库分表利器一-Sharding-JDBC实战等等内容。
我将分别从源码、手撸框架、实战演练等多个方面进行多维度深入讲解,让大家轻松掌握分布式各种解决方案。
首先我要问大家一个问题:大型项目分布式系统核心问题你能解决多少?
1、分布式锁
1.你知道Etcd如何实现分布式锁的吗?
2.你知道Redis实现的分布式锁存在什么问题吗?
3.不同分布式锁实现方案的优缺点你清楚了吗?
4.如果让你手撸实现Redis分布式锁,你可以做到吗?
2、分布式事务
1.你知道为什么CAP不能同时满足吗?
2.你了解不同分布式事务解决方案对应什么样的应用场景么 ?
3.你知道为什么大多数业务场景都选择了最终一致性实现方案么?
4.你了解Seata框架为什么当下如此受欢迎么?
3、分布式ID
1.这么多种分布式ID生成方式,应该选择哪种呢?
2.雪花算法底层实现原理是什么?
4、分库分表
1.当数据量大了之后,我们应该如何选择分库分表的解决方案?
2.做分库分表,是应该垂直切分还是水平切分?
带着这些问题,我们一起来展开代码实战:
新增和修改我们封装一个通用方法 updateItem(),该方法传入两个参数:storeName、data,storeName表示对象仓库名称,data是一个对象,包含主键和索引,在调用indexedDB所提供的 put()方法,在新增操作的时候不需要传入索引的键值对,修改操作的时候在该方法中另外多传递一个主键的键值对,这样才能根据id去修改对应的某一条数据。
updateItem(storeName: string, data: any) {
console.log(this.db)
const store = this.db.transaction([storeName], 'readwrite').objectStore(storeName)
const request = store.put({
...data,
updateTIme: new Date().getTime()
})
request.onsuccess = (event: any) => {
console.log('数据写入成功')
console.log(event)
}
request.onerror = (event: any) => {
console.log('数据写入失败')
console.log(event)
}
}
关键点是根据传入 key即为主键 id的值来查询某一条数据,需要使用到 indexedDB提供的 get() 方法来实现查询操作。
getItem(storeName: string, key: number | string) {
const store = this.db.transaction([storeName], 'readwrite').objectStore(storeName)
const request = store.get(key)
request.onsuccess = (event: any) => {
console.log('查询某一条数据成功')
console.log(event.target.result)
}
request.onerror = (event: any) => {
console.log('查询某一条数据失败')
console.log(event)
}
}
为了更好的获取indexedD事务中的返回结果,我们使用promise来包装一下上一小节indexedDB.ts中定义的几个方法:openStore、updateItem、deleteItem、getList、getItem。下面代码片段为getList()
// 查询所有数据
getList(storeName: string) {
const store = this.db.transaction(storeName).objectStore(storeName)
const request = store.getAll()
return new Promise((resolve, reject) => {
request.onsuccess = (event: any) => {
console.log('查询所有数据成功')
console.log(event.target.result)
resolve(event.target.result)
}
request.onerror = (event: any) => {
console.log('查询所有数据失败')
console.log(event)
reject(event)
}
})
}
在第一步中,首先使用 Typescript的 interface为 store中的所有 state声明类型,然后将 interface放置在InjectionKeyd的泛型类型中,代码片段如下:
// src/store/index.ts
import { createStore, Store } from 'vuex'
import { InjectionKey } from 'vue'
// 为 store state 声明类型
export interface AllStateTypes {
count: number,
locale: any,
userStatus: Number
}
// 定义 injection key
export const key: InjectionKey<Store<AllStateTypes>> = Symbol('storeKey')
export const store = createStore<AllStateTypes>({
// ...
})
通过环境变量区分 server.js中的一些代码片段,因为有些代码需要运行在开发环境,而有些代码需要运行在生产环境。本小节在 server.js中一共对3个地方进行了环境区分,代码片段如下:
// server.js
if (!isProd) {
// 1. 读取 index.html
template = fs.readFileSync(
path.resolve(__dirname, 'index.html'),
'utf-8'
)
// 2. 应用 Vite HTML 转换。这将会注入 Vite HMR 客户端,
// 同时也会从 Vite 插件应用 HTML 转换。
// 例如:@vitejs/plugin-react-refresh 中的 global preambles
template = await vite.transformIndexHtml(url, template)
// 3. 加载服务器入口。vite.ssrLoadModule 将自动转换
// 你的 ESM 源码使之可以在 Node.js 中运行!无需打包
// 并提供类似 HMR 的根据情况随时失效。
render = (await vite.ssrLoadModule('/src/entry-server.ts')).render
} else {
// 1. 读取 index.html
template = fs.readFileSync(
path.resolve(__dirname, 'dist/client/index.html'),
'utf-8'
)
// 3. 加载服务器入口
render = require('./dist/server/entry-server.ts').render
}
fetchElephant()接口中有两个 await,分别依次执行连接数据库和查询数据的操作,我们接下来在 home.vue中引入这个 Mock接口,然后调用,代码片段如下所示:
// home.vue
// Mock接口
function getElephant() {
fetchElephant().then(res => {
console.log('Mock接口', res)
})
}
getElephant()
通过 emit触发父组件上的事件,将 language传递给父组件,并赋值给父组件中的全局组件<ElConfigProvider /> 上的 locale属性,同样也赋值给 useI18n()实例上的 locale属性,这样就可以实现在子组件 headearCommon.vue中进行国际化切换操作并作用到父组件 App.vue中
版权说明:本资料由用户提供并上传,仅用于学习交流;若内容存在侵权,请进行举报,或
联系我们 删除。