npm gitbook 文档编辑生成器
first step : npm install -g gitbook-cli
second step : gitbook init
third step: gitbook serve (and your application is running on port 4000)
npm gitbook 文档编辑生成器
first step : npm install -g gitbook-cli
second step : gitbook init
third step: gitbook serve (and your application is running on port 4000)
可用的元素声明
abstract abstract
abstract class “abstract class”
annotation annotation
circle circle
class class
diamond diamond
entity entity
enum enum
interface interface
类实体关系
Type Symbol
Extension(扩展) <|–
Composition(组合) *–
Aggregation(聚合) o–
也可以使用 extends implement
定义属性与方法
Object : equals()
ArrayList : Object[] elementData
ArrayList : size()
通过 类对象 : 方法 / 属性 定义
也可以
class
{
嵌套在类
Object[] elementData
int size()
返回属性后置
flightNumber : Integer
departureTime : Date
强制声明为field 或 method 否则根据 是否有括号判断
{field} A field
{method} Some method
}
可访问性
Character Icon for field Icon for method Visibility
-private
#protected
~ package private
+public
抽象与静态
@startuml
class Dummy {
{static} String id
{abstract} void methods()
}
@enduml
plantuml 是uml 的其中一种标准和实现形式
其代码逻辑实现由java 通过正则表达式 逐行逐行 解析uml文本
然后 生成uml的数据结构 实体的结构 关联结构 等。
具体 命令行用法
java -jar pantuml.jar XXX.puml -o XXX.png
可以把XXX.puml 转化为 png的可视化关联对象图片
以@startuml @enduml 包裹 uml代码
@startuml
开始uml
@enduml
结束uml
!inlcude $umlfile
包含/嵌套 其他uml文件
title $title
定义 uml title
title
end title
定义多行title
定义实体后 as 可以起别名
今天,我们将通过介绍 Laravel 中一个不太为人所知的功能,来展示如何快捷的调试数据库中的数据。通过使用 Laravel artisan 内建的 php artisan tinker, 我们可以很方便的看到数据库中的数据并且执行各种想要的操作。
Laravel artisan 的 tinker 是一个 REPL (read-eval-print-loop),REPL 是指交互式命令行界面,它可以让你输入一段代码去执行,并把执行结果直接打印到命令行界面里。
// see the count of all users
App\User::count();
// find a specific user and see their attributes
App\User::where('username', 'samuel')->first();
// find the relationships of a user
$user = App\User::with('posts')->first();
$user->posts;
factory(App\User::class, 10)->create();
App\User::all();
App\User::count();
$user = new App\User;
$user->name = "Wruce Bayne";
$user->email = "iambatman@savegotham.com";
$user->save();
doc XXX
查阅某个方法的文档
show XXX
显示某个方法的代码
laravel 的form 对象 有magic方法 可以快速添加表单项
/**
* Class Form.
*
* @method Field\Text text($name, $label = '')
* @method Field\Password password($name, $label = '')
* @method Field\Checkbox checkbox($name, $label = '')
* @method Field\CheckboxButton checkboxButton($name, $label = '')
* @method Field\CheckboxCard checkboxCard($name, $label = '')
* @method Field\Radio radio($name, $label = '')
* @method Field\RadioButton radioButton($name, $label = '')
* @method Field\RadioCard radioCard($name, $label = '')
* @method Field\Select select($name, $label = '')
* @method Field\MultipleSelect multipleSelect($name, $label = '')
* @method Field\Textarea textarea($name, $label = '')
* @method Field\Hidden hidden($name, $label = '')
* @method Field\Id id($name, $label = '')
* @method Field\Ip ip($name, $label = '')
* @method Field\Url url($name, $label = '')
* @method Field\Color color($name, $label = '')
* @method Field\Email email($name, $label = '')
* @method Field\Mobile mobile($name, $label = '')
* @method Field\Slider slider($name, $label = '')
* @method Field\File file($name, $label = '')
* @method Field\Image image($name, $label = '')
* @method Field\Date date($name, $label = '')
* @method Field\Datetime datetime($name, $label = '')
* @method Field\Time time($name, $label = '')
* @method Field\Year year($column, $label = '')
* @method Field\Month month($column, $label = '')
* @method Field\DateRange dateRange($start, $end, $label = '')
* @method Field\DateTimeRange dateTimeRange($start, $end, $label = '')
* @method Field\TimeRange timeRange($start, $end, $label = '')
* @method Field\Number number($name, $label = '')
* @method Field\Currency currency($name, $label = '')
* @method Field\SwitchField switch($name, $label = '')
* @method Field\Display display($name, $label = '')
* @method Field\Rate rate($name, $label = '')
* @method Field\Divider divider($title = '')
* @method Field\Decimal decimal($column, $label = '')
* @method Field\Html html($html)
* @method Field\Tags tags($column, $label = '')
* @method Field\Icon icon($column, $label = '')
* @method Field\Captcha captcha($column, $label = '')
* @method Field\Listbox listbox($column, $label = '')
* @method Field\Table table($column, $label, $builder)
* @method Field\Timezone timezone($column, $label = '')
* @method Field\KeyValue keyValue($column, $label = '')
* @method Field\ListField list($column, $label = '')
* @method mixed handle(Request $request)
*/
真实调用的方法
/**
* Generate a Field object and add to form builder if Field exists.
*
* @param string $method
* @param array $arguments
*
* @return Field|$this
*/
public function __call($method, $arguments)
{
if (!$this->hasField($method)) {
return $this;
}
$class = BaseForm::$availableFields[$method];
$field = new $class(Arr::get($arguments, 0), array_slice($arguments, 1));
return tap($field, function ($field) {
$this->pushField($field);
});
}
__call 属于php 类对象的magic 方法
当调用一个不存在与类定义的方法 就会 在call中调用
function __call($name,$arguments) {
}
$name 为方法名字
$argument 为方法参数
服务发现是 服务治理的一个很重要的点
所有注册在服务平台的微服务 必须要能被发现 然后调用
而我们调用其他服务一般有三种方法
DiscoverClient ribbon Feign
DiscoverClient 是更加低层的方法 当DiscoverClient 需要寻找服务时 其实是向服务注册器(例如 eureka) 发送 http 请求获取躯体服务信息 包括 ip port 等
@SpringBootApplication
@EnableDiscoveryClient
class Application {
@Autowired
DiscoveryClient discoveryClient
}
添加了注解@EnableDiscoveryClient
然后就能自动 注入 discoverClient
@Autowired
DiscoveryClient discoveryClient
def restTemplate = new RestTemplate()
def serverList = discoveryClient.getInstances("ROBIN-ADMIN")
println(serverList)
restTemplate.getForObject("${serverList[0].getUri()}/api/ribbon",Map.class)
获取到discoverClient 就能通过 服务名字 查找服务实例 并且通过RestTemplate 调用服务接口了
Ribbon是调用了 discoverClient 调用服务的 但是他提供了 负载均衡功能,不显式调用某个服务实例 而是通过策略调用某类服务的其中一个 达到负载均衡效果
@SpringBootApplication
class RibbonApplication {
@Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate()
}
}
在注册RestTemplate对象时 添加LoadBalanced 注解
LoadBalanced 会自动实例化restTemplate 的服务均衡策略 具体查看LoadBalance接口 会定时ping各个服务实例 也会用譬如 回环轮询策略 寻找服务实例
当restTemplate 调用服务时 通过策略调用服务实例
restTemplate.getForObject("http://ROBIN-ADMIN/api/health",Map.class)
ROBIN-ADMIN 为某类服务的服务ID
Feign 是更加接近业务的服务调用方式
maven 添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
添加Feign注解
@EnableFeignClients
class RibbonApplication {
}
新建接口对象
package org.robin.ribbon.feign
import org.springframework.cloud.openfeign.FeignClient
import org.springframework.web.bind.annotation.RequestMapping
@FeignClient("ROBIN-ADMIN")
interface RobinAdminService {
@RequestMapping("/api/ribbon")
Map ribbon()
@RequestMapping("/api/health")
Map health()
}
spring会自动生成 RobinAdminService
调用该对象的方法 可以 调用对应微服务的接口
使用laravel 的数据库Facade 可以比较好的 执行数据库sql
$array = DB::select("select * from admin_users");
//raw 执行sql
$object = DB::table("admin_users")->where("id","=","1")->first();
//获取查询第一条
$array = DB::table("admin_users")->where("id","=","1")->get();
//
get获取数据列表
$array = DB::table("admin_users")->where("id","=","1")->skip(0)->take(1)->get();
//分页查询
$array = DB::table("admin_users")->where("id","=","1")->skip(0)->limit(1)->get();
//分页查询
DB::transaction(function (){
//内部执行开启事务
});
//手动控制事务
DB::beginTransaction();
DB::commit();
DB::rollBack();

作为微服务服务注册供应方
默认在本机 http://localhost:8761/eureka/提供服务
注册请求地址在 apps/{service-name} POST 发送本机服务信息
注销请求地址在 apps/{service-name}/{id} DELETE 发送请求
心跳请求地址在 apps/{service-name}/{id} PUT 发送请求
状态请求地址在 apps/{service-name}/{id}/status PUT 发送请求
删除状态请求地址在 apps/{service-name}/{id}/status DELETE 发送请求
php socket 第三方库 composer require react/socket
该库针对 socket / 流 做事件监听(应该是epoll )主线程做事件循环 (reactive)所以该reactive 框架貌似只能在 linux下使用
server
<?php
require '../vendor/autoload.php';
echo "enter script\n";
$loop = React\EventLoop\Factory::create();
$socket = new React\Socket\Server('127.0.0.1:8080', $loop);
$socket->on('connection', function (React\Socket\ConnectionInterface $connection) {
echo "" . $connection->getRemoteAddress() . "client connected\n";
$connection->write("Hello " . $connection->getRemoteAddress() . "!\n");
$connection->write("Welcome to this amazing server!\n");
$connection->write("Here's a tip: don't say anything.\n");
$connection->on('data', function ($data) use ($connection) {
echo "" . $data . "\n";
//$connection->close();
});
});
echo "server started at 8080\n";
$loop->run();
其中$loop 就是事件循环对象
client
<?php
require '../vendor/autoload.php';
$loop = React\EventLoop\Factory::create();
$connector = new React\Socket\Connector($loop);
$connector->connect('127.0.0.1:8080')->then(function (React\Socket\ConnectionInterface $connection) use ($loop) {
echo "client connected\n";
$connection->write("Hello World!\n");
$connection->on('data', function ($data) use ($loop, $connection) {
echo "" . $data . "\n";
//$connection->close();
//$output = new React\Stream\WritableResourceStream(fopen("./client.txt", "w"),$loop);
//$output = fopen("./client.txt", "w");
//fwrite($output,$data);
//$output->write("" . $data . "\n");
while($input = fgets(STDIN, 10))
{
echo $input."\n";
$connection->write($input);
}
});
/*
$input = new React\Stream\ReadableResourceStream(STDIN,$loop);
$input->on("data",function ($data) use ($connection) {
$connection->write($data);
});*/
//$output = fopen("./client.txt", "w");
//$steam = new React\Stream\WritableResourceStream($output,$loop);
//$connection->pipe($steam);
});
$loop->run();
最亮眼的是 将文件描述符(标准输出流 文件输出流)fd 包装成一个响应式流对象 通过pipe实现管道功能 而且生命周期相同 会同时关闭。